Ejemplo n.º 1
0
        /// <summary>
        /// This tool builds the additional vertex stream for each primitive that will attach the best probe ID (as a U16)
        ///  to a vertex so the vertex shader has a single entry point into the probes network
        /// Most face indices have already been rendered in the probe cube map and the batch processing tool took care of
        ///  selecting the most important probe for these faces, but some faces don't have probe information.
        ///  Maybe they have been occluded by other faces (shadowing) or are too small to be rendered in the cube map.
        /// For these special faces, we need to propagate probe IDs from valid faces until the entire mesh is filled with
        ///  valid probe IDs.
        /// 
        /// We proceed primitive per primitive since they are all disconnected so no propagation would be possible cross
        ///  primitives unless we could reconnect split vertices, but I don't want to do that. Maybe it will become necessary
        ///  at some point but for the moment I don't care.
        /// Some primitives may lack probe ID completely (!!), for these I choose to assign the ID of the nearest probe, which
        ///  may be a bit dangerous, especially if we're dealing with probes that are standing right behind the primitive for example.
        /// In that case, perhaps using a scoring scheme that depends on both distance and orientation would be better? Let's see that when the problem arises...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void encodeFaceProbesToolStripMenuItem_Click( object sender, EventArgs e )
        {
            // Ask for the influence file to load from
            string	OldFileName = GetRegKey( "LastProbeInfluenceFileName", GetRegKey( "LastProbesFolderTarget", Path.GetDirectoryName( m_ApplicationPath ) ) );
            openFileDialogProbeInfluence.InitialDirectory = Path.GetDirectoryName( OldFileName );
            openFileDialogProbeInfluence.FileName = Path.GetFileName( OldFileName );
            if ( openFileDialogProbeInfluence.ShowDialog( this ) != DialogResult.OK )
                return;
            SetRegKey( "LastProbeInfluenceFileName", openFileDialogProbeInfluence.FileName );

            FileInfo	SourceInfluenceFile = new FileInfo( openFileDialogProbeInfluence.FileName );

            // Ask for the scene file to apply to
            string	OldSceneFile = GetRegKey( "LastSceneFileName", GetRegKey( "LastProbesFolderSource", Path.GetDirectoryName( m_ApplicationPath ) ) );
            openFileDialogScene.InitialDirectory = Path.GetDirectoryName( OldSceneFile );
            openFileDialogScene.FileName = Path.GetFileName( OldSceneFile );
            if ( openFileDialogScene.ShowDialog( this ) != DialogResult.OK )
                return;
            SetRegKey( "LastSceneFileName", openFileDialogScene.FileName );

            FileInfo	SceneFile = new FileInfo( openFileDialogScene.FileName );

            try
            {
                // Read the scene file
                GCXFormat.Scene	GCX = null;
                using ( FileStream S = SceneFile.OpenRead() )
                    using( BinaryReader R = new BinaryReader( S ) )
                        GCX = new GCXFormat.Scene( R );

                // Read the probe influences
                ProbeInfluence[]	FaceInfluences = new ProbeInfluence[GCX.m_TotalFacesCount];
                using ( FileStream S = SourceInfluenceFile.OpenRead() )
                    using( BinaryReader R = new BinaryReader( S ) )
                    {
                        int	SizeofProbeInfluence = System.Runtime.InteropServices.Marshal.SizeOf(typeof(UInt32)) + System.Runtime.InteropServices.Marshal.SizeOf(typeof(double));
                        int	FacesCount = (int) S.Length / SizeofProbeInfluence;
                        if ( (S.Length % SizeofProbeInfluence) != 0 )
                            throw new Exception( "Probe influence file is larger than an integer number of ProbeInfluence structures!" );

                        for ( int FaceIndex=0; FaceIndex < FacesCount; FaceIndex++ )
                        {
                            UInt32	ProbeID = R.ReadUInt32();
                            double	Importance = R.ReadDouble();
                            FaceInfluences[FaceIndex] = new ProbeInfluence() { ProbeID = ProbeID, Importance = Importance };
                        }
                        for ( int FaceIndex=FacesCount; FaceIndex < GCX.m_TotalFacesCount; FaceIndex++ )
                            FaceInfluences[FaceIndex] = new ProbeInfluence() { ProbeID = ProbeInfluence.INVALID_PROBEID, Importance = 0.0 };
                    }

                UInt32[]	VertexStreamProbeID = new UInt32[GCX.m_TotalVerticesCount];	// The final vertex stream we're building

                // Establish data for progress measurement
                int	PrimitivesCount = 0;
                foreach ( GCXFormat.Scene.Node N in GCX.m_Nodes )
                {
                    GCXFormat.Scene.Mesh	M = N as GCXFormat.Scene.Mesh;
                    if ( M != null )
                        PrimitivesCount += M.m_Primitives.Length;
                }

                //////////////////////////////////////////////////////////////////////////
                // The algorithm is quite simple:
                //	For each primitive
                //		Create a winged edge structure for each face
                //		Assign known probe influence to each face
                //		Build a list of faces without probe influence
                //
                //		While list is not empty and its size keeps decreasing
                //			For each face without influence
                //				If neighbor faces have influence information
                //					Copy best influence from neighbor
                //					Remove face from the list
                //
                //		If list is not empty			// We have a bunch of disconnected faces that can't see any probe
                //			For each face of the list
                //				Assign [NO PROBE|NEAREST PROBE|WORLD PROBE] ? (not clear yet which is best)
                //
                //		Redistribute best probe's ID to each face vertex
                //
                //	Save stream of vertex probe IDs to be merged into an additional vertex buffer stream at runtime
                //
                int	MeshIndex = 0;
                int	PrimitiveIndex = 0;
                int	FacesWithoutProbeCount = 0;
                int	PrimitivesWithoutProbeCount = 0;
                string	Errors = "";

                progressBarBatchConvert.Value = 0;
                progressBarBatchConvert.Visible = true;
                progressBarSubTask.Value = 0;
                progressBarSubTask.Visible = true;

                foreach ( GCXFormat.Scene.Node N in GCX.m_Nodes )
                {
                    GCXFormat.Scene.Mesh	M = N as GCXFormat.Scene.Mesh;
                    if ( M == null )
                        continue;

                    foreach ( GCXFormat.Scene.Mesh.Primitive P in M.m_Primitives )
                    {
                        int	FacesCount = P.m_Faces.Length;

                        try
                        {
                            P.BuildWingedEdgesMesh();
                        }
                        catch ( Exception _e )
                        {
                            Errors += "Primitive #" + PrimitiveIndex + " of mesh #" + MeshIndex + " has generated an error on Winged Mesh generation: " + _e.Message + "\r\n";

                            // Add this primitve to the list of the ones m
                            PrimitivesWithoutProbeCount++;
                            FacesWithoutProbeCount += P.m_Vertices.Length;
                            continue;
                        }

                        // Update progress
                        progressBarBatchConvert.Value = progressBarBatchConvert.Maximum * (++PrimitiveIndex) / PrimitivesCount;
                        progressBarSubTask.Value = 0;

                        // Tag winged edge faces with probe influence & list faces without valid probe ID
                        List<GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle>	MissingProbeIDFaces = new List<GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle>( FacesCount );
                        for ( int FaceIndex=0; FaceIndex < FacesCount; FaceIndex++ )
                        {
                            ProbeInfluence	Influence = FaceInfluences[P.m_FaceOffset+FaceIndex];
                            GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle	Face = P.m_WingedEdgeFaces[FaceIndex];
                            Face.m_Tag = Influence;
                            if ( Influence.ProbeID == ProbeInfluence.INVALID_PROBEID )
                                MissingProbeIDFaces.Add( Face );
                        }

                        // Propagate probe influence
                        int	OriginalCount = MissingProbeIDFaces.Count;
                        int	LastListSize = MissingProbeIDFaces.Count+1;
                        while ( MissingProbeIDFaces.Count > 0 && MissingProbeIDFaces.Count < LastListSize )
                        {
                            LastListSize = MissingProbeIDFaces.Count;	// Keep track of list's size so we know if anything moved
                            for ( int FaceIndex=MissingProbeIDFaces.Count-1; FaceIndex >= 0; FaceIndex-- )	// Browse backward so we can safely remove elements from the list
                            {
                                GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle	Face = MissingProbeIDFaces[FaceIndex];

                                // Examine neighbors' probe influence and propagate best probe
                                ProbeInfluence	BestProbe = null;
                                for ( int EdgeIndex=0; EdgeIndex < 3; EdgeIndex++ )
                                {
                                    int	NeighborFaceIndex = Face.m_Edges[EdgeIndex].GetOtherFaceIndex( Face.m_Index );
                                    if ( NeighborFaceIndex != -1 )
                                    {
                                        GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle	NeighborFace = P.m_WingedEdgeFaces[NeighborFaceIndex];
                                        ProbeInfluence	NeighborProbe = NeighborFace.m_Tag as ProbeInfluence;
                                        if ( NeighborProbe.ProbeID != ProbeInfluence.INVALID_PROBEID && (BestProbe == null || NeighborProbe.Importance > BestProbe.Importance) )
                                            BestProbe = NeighborProbe;	// Found a better probe for that face!
                                    }
                                }

                                if ( BestProbe == null )
                                    continue;	// Still no valid probe found...

                                Face.m_Tag = BestProbe;	// Share the probe, don't care...
                                MissingProbeIDFaces.RemoveAt( FaceIndex );	// We can safely remove the face by index since we're browsing the list backward
                            }

                            // Update progress
                            progressBarSubTask.Value = progressBarSubTask.Maximum * (OriginalCount - MissingProbeIDFaces.Count) / OriginalCount;
                            progressBarSubTask.Refresh();
                        }

                        // At this point, either the list of faces missing probe IDs is empty in which case the job is done
                        //	or we need to assign an arbitrary probe ID to those faces
                        if ( MissingProbeIDFaces.Count > 0 )
                        {
                            FacesWithoutProbeCount += MissingProbeIDFaces.Count;
                            PrimitivesWithoutProbeCount++;

                            // TODO: Assign nearest probe or something!
                        }

                        // Now that we have valid probe IDs for each face, propagate best probe influence to each vertex
                        ProbeInfluence[]	BestProbePerVertex = new ProbeInfluence[P.m_Vertices.Length];
                        for ( int FaceIndex=0; FaceIndex < FacesCount; FaceIndex++ )
                        {
                            GCXFormat.Scene.Mesh.Primitive.Face	Face = P.m_Faces[FaceIndex];
                            ProbeInfluence	FaceProbe = P.m_WingedEdgeFaces[FaceIndex].m_Tag as ProbeInfluence;

                            if ( BestProbePerVertex[Face.V0] == null || BestProbePerVertex[Face.V0].Importance < FaceProbe.Importance )	BestProbePerVertex[Face.V0] = FaceProbe;	// Better probe for that vertex
                            if ( BestProbePerVertex[Face.V1] == null || BestProbePerVertex[Face.V1].Importance < FaceProbe.Importance )	BestProbePerVertex[Face.V1] = FaceProbe;	// Better probe for that vertex
                            if ( BestProbePerVertex[Face.V2] == null || BestProbePerVertex[Face.V2].Importance < FaceProbe.Importance )	BestProbePerVertex[Face.V2] = FaceProbe;	// Better probe for that vertex
                        }

                        // Finally, we can splat probe IDs into the giant vertex stream
                        for ( int VertexIndex=0; VertexIndex < P.m_Vertices.Length; VertexIndex++ )
                            VertexStreamProbeID[P.m_VertexOffset+VertexIndex] = (UInt32) (BestProbePerVertex[VertexIndex] != null ? BestProbePerVertex[VertexIndex].ProbeID : 0xFFFFFFFF);	// TODO <= warn if we still have invalid vertices!
                    }

                    MeshIndex++;
                }

                progressBarBatchConvert.Value = progressBarBatchConvert.Maximum;

                //////////////////////////////////////////////////////////////////////////
                // Save the final vertex stream to disk
                FileInfo	TargetVertexStreamFile = new FileInfo( Path.Combine( Path.GetDirectoryName( SceneFile.FullName ), Path.GetFileNameWithoutExtension( SceneFile.FullName ) + "_ProbeID.vertexStream.U16" ) );

                using ( FileStream S = TargetVertexStreamFile.Create() )
                    using( BinaryWriter W = new BinaryWriter( S ) )
                    {
                        for ( int VertexIndex=0; VertexIndex < VertexStreamProbeID.Length; VertexIndex++ )
                            W.Write( VertexStreamProbeID[VertexIndex] );
                    }

                // Notify
                MessageBoxIcon	Icon = MessageBoxIcon.Information;
                string	Info  = "Success!\r\n";
                        Info += "Processed " + PrimitivesCount + " primitives for a total of " + GCX.m_TotalFacesCount + " faces and " + GCX.m_TotalVerticesCount + " vertices.\r\n";
                if ( PrimitivesWithoutProbeCount > 0 )
                {
                    Icon = MessageBoxIcon.Warning;
                    Info += "\r\n---------------------- WARNING ----------------------\r\n";
                    Info += PrimitivesWithoutProbeCount + " primitives are missing or have incomplete probe information.\r\n";
                    Info += "A total of " + FacesWithoutProbeCount + " faces don't have probe information!\r\n";
                }
                if ( Errors != "" )
                {
                    Icon = MessageBoxIcon.Warning;
                    Info += "\r\n---------------------- ERRORS ----------------------\r\n";
                    Info += Errors;
                }
                MessageBox( Info, MessageBoxButtons.OK, Icon );
            }
            catch ( Exception _e )
            {
                MessageBox( "An error occurred while probe influences in scene file: " + _e.Message, MessageBoxButtons.OK, MessageBoxIcon.Error );
                return;
            }
            finally
            {
                progressBarBatchConvert.Visible = false;
                progressBarSubTask.Visible = false;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This tool builds the additional vertex stream for each primitive that will attach the best probe ID (as a U16)
        ///  to a vertex so the vertex shader has a single entry point into the probes network
        /// Most face indices have already been rendered in the probe cube map and the batch processing tool took care of
        ///  selecting the most important probe for these faces, but some faces don't have probe information.
        ///  Maybe they have been occluded by other faces (shadowing) or are too small to be rendered in the cube map.
        /// For these special faces, we need to propagate probe IDs from valid faces until the entire mesh is filled with
        ///  valid probe IDs.
        ///
        /// We proceed primitive per primitive since they are all disconnected so no propagation would be possible cross
        ///  primitives unless we could reconnect split vertices, but I don't want to do that. Maybe it will become necessary
        ///  at some point but for the moment I don't care.
        /// Some primitives may lack probe ID completely (!!), for these I choose to assign the ID of the nearest probe, which
        ///  may be a bit dangerous, especially if we're dealing with probes that are standing right behind the primitive for example.
        /// In that case, perhaps using a scoring scheme that depends on both distance and orientation would be better? Let's see that when the problem arises...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void encodeFaceProbesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Ask for the influence file to load from
            string OldFileName = GetRegKey("LastProbeInfluenceFileName", GetRegKey("LastProbesFolderTarget", Path.GetDirectoryName(m_ApplicationPath)));

            openFileDialogProbeInfluence.InitialDirectory = Path.GetDirectoryName(OldFileName);
            openFileDialogProbeInfluence.FileName         = Path.GetFileName(OldFileName);
            if (openFileDialogProbeInfluence.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }
            SetRegKey("LastProbeInfluenceFileName", openFileDialogProbeInfluence.FileName);

            FileInfo SourceInfluenceFile = new FileInfo(openFileDialogProbeInfluence.FileName);

            // Ask for the scene file to apply to
            string OldSceneFile = GetRegKey("LastSceneFileName", GetRegKey("LastProbesFolderSource", Path.GetDirectoryName(m_ApplicationPath)));

            openFileDialogScene.InitialDirectory = Path.GetDirectoryName(OldSceneFile);
            openFileDialogScene.FileName         = Path.GetFileName(OldSceneFile);
            if (openFileDialogScene.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }
            SetRegKey("LastSceneFileName", openFileDialogScene.FileName);

            FileInfo SceneFile = new FileInfo(openFileDialogScene.FileName);

            try
            {
                // Read the scene file
                GCXFormat.Scene GCX = null;
                using (FileStream S = SceneFile.OpenRead())
                    using (BinaryReader R = new BinaryReader(S))
                        GCX = new GCXFormat.Scene(R);

                // Read the probe influences
                ProbeInfluence[] FaceInfluences = new ProbeInfluence[GCX.m_TotalFacesCount];
                using (FileStream S = SourceInfluenceFile.OpenRead())
                    using (BinaryReader R = new BinaryReader(S))
                    {
                        int SizeofProbeInfluence = System.Runtime.InteropServices.Marshal.SizeOf(typeof(UInt32)) + System.Runtime.InteropServices.Marshal.SizeOf(typeof(double));
                        int FacesCount           = (int)S.Length / SizeofProbeInfluence;
                        if ((S.Length % SizeofProbeInfluence) != 0)
                        {
                            throw new Exception("Probe influence file is larger than an integer number of ProbeInfluence structures!");
                        }

                        for (int FaceIndex = 0; FaceIndex < FacesCount; FaceIndex++)
                        {
                            UInt32 ProbeID    = R.ReadUInt32();
                            double Importance = R.ReadDouble();
                            FaceInfluences[FaceIndex] = new ProbeInfluence()
                            {
                                ProbeID = ProbeID, Importance = Importance
                            };
                        }
                        for (int FaceIndex = FacesCount; FaceIndex < GCX.m_TotalFacesCount; FaceIndex++)
                        {
                            FaceInfluences[FaceIndex] = new ProbeInfluence()
                            {
                                ProbeID = ProbeInfluence.INVALID_PROBEID, Importance = 0.0
                            }
                        }
                        ;
                    }

                UInt32[] VertexStreamProbeID = new UInt32[GCX.m_TotalVerticesCount];                            // The final vertex stream we're building


                // Establish data for progress measurement
                int PrimitivesCount = 0;
                foreach (GCXFormat.Scene.Node N in GCX.m_Nodes)
                {
                    GCXFormat.Scene.Mesh M = N as GCXFormat.Scene.Mesh;
                    if (M != null)
                    {
                        PrimitivesCount += M.m_Primitives.Length;
                    }
                }

                //////////////////////////////////////////////////////////////////////////
                // The algorithm is quite simple:
                //	For each primitive
                //		Create a winged edge structure for each face
                //		Assign known probe influence to each face
                //		Build a list of faces without probe influence
                //
                //		While list is not empty and its size keeps decreasing
                //			For each face without influence
                //				If neighbor faces have influence information
                //					Copy best influence from neighbor
                //					Remove face from the list
                //
                //		If list is not empty			// We have a bunch of disconnected faces that can't see any probe
                //			For each face of the list
                //				Assign [NO PROBE|NEAREST PROBE|WORLD PROBE] ? (not clear yet which is best)
                //
                //		Redistribute best probe's ID to each face vertex
                //
                //	Save stream of vertex probe IDs to be merged into an additional vertex buffer stream at runtime
                //
                int    MeshIndex                   = 0;
                int    PrimitiveIndex              = 0;
                int    FacesWithoutProbeCount      = 0;
                int    PrimitivesWithoutProbeCount = 0;
                string Errors = "";

                progressBarBatchConvert.Value   = 0;
                progressBarBatchConvert.Visible = true;
                progressBarSubTask.Value        = 0;
                progressBarSubTask.Visible      = true;

                foreach (GCXFormat.Scene.Node N in GCX.m_Nodes)
                {
                    GCXFormat.Scene.Mesh M = N as GCXFormat.Scene.Mesh;
                    if (M == null)
                    {
                        continue;
                    }

                    foreach (GCXFormat.Scene.Mesh.Primitive P in M.m_Primitives)
                    {
                        int FacesCount = P.m_Faces.Length;

                        try
                        {
                            P.BuildWingedEdgesMesh();
                        }
                        catch (Exception _e)
                        {
                            Errors += "Primitive #" + PrimitiveIndex + " of mesh #" + MeshIndex + " has generated an error on Winged Mesh generation: " + _e.Message + "\r\n";

                            // Add this primitve to the list of the ones m
                            PrimitivesWithoutProbeCount++;
                            FacesWithoutProbeCount += P.m_Vertices.Length;
                            continue;
                        }

                        // Update progress
                        progressBarBatchConvert.Value = progressBarBatchConvert.Maximum * (++PrimitiveIndex) / PrimitivesCount;
                        progressBarSubTask.Value      = 0;

                        // Tag winged edge faces with probe influence & list faces without valid probe ID
                        List <GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle> MissingProbeIDFaces = new List <GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle>(FacesCount);
                        for (int FaceIndex = 0; FaceIndex < FacesCount; FaceIndex++)
                        {
                            ProbeInfluence Influence = FaceInfluences[P.m_FaceOffset + FaceIndex];
                            GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle Face = P.m_WingedEdgeFaces[FaceIndex];
                            Face.m_Tag = Influence;
                            if (Influence.ProbeID == ProbeInfluence.INVALID_PROBEID)
                            {
                                MissingProbeIDFaces.Add(Face);
                            }
                        }

                        // Propagate probe influence
                        int OriginalCount = MissingProbeIDFaces.Count;
                        int LastListSize  = MissingProbeIDFaces.Count + 1;
                        while (MissingProbeIDFaces.Count > 0 && MissingProbeIDFaces.Count < LastListSize)
                        {
                            LastListSize = MissingProbeIDFaces.Count;                                        // Keep track of list's size so we know if anything moved
                            for (int FaceIndex = MissingProbeIDFaces.Count - 1; FaceIndex >= 0; FaceIndex--) // Browse backward so we can safely remove elements from the list
                            {
                                GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle Face = MissingProbeIDFaces[FaceIndex];

                                // Examine neighbors' probe influence and propagate best probe
                                ProbeInfluence BestProbe = null;
                                for (int EdgeIndex = 0; EdgeIndex < 3; EdgeIndex++)
                                {
                                    int NeighborFaceIndex = Face.m_Edges[EdgeIndex].GetOtherFaceIndex(Face.m_Index);
                                    if (NeighborFaceIndex != -1)
                                    {
                                        GCXFormat.Scene.Mesh.Primitive.WingedEdgeTriangle NeighborFace = P.m_WingedEdgeFaces[NeighborFaceIndex];
                                        ProbeInfluence NeighborProbe = NeighborFace.m_Tag as ProbeInfluence;
                                        if (NeighborProbe.ProbeID != ProbeInfluence.INVALID_PROBEID && (BestProbe == null || NeighborProbe.Importance > BestProbe.Importance))
                                        {
                                            BestProbe = NeighborProbe;                                                  // Found a better probe for that face!
                                        }
                                    }
                                }

                                if (BestProbe == null)
                                {
                                    continue;                                           // Still no valid probe found...
                                }
                                Face.m_Tag = BestProbe;                                 // Share the probe, don't care...
                                MissingProbeIDFaces.RemoveAt(FaceIndex);                // We can safely remove the face by index since we're browsing the list backward
                            }

                            // Update progress
                            progressBarSubTask.Value = progressBarSubTask.Maximum * (OriginalCount - MissingProbeIDFaces.Count) / OriginalCount;
                            progressBarSubTask.Refresh();
                        }

                        // At this point, either the list of faces missing probe IDs is empty in which case the job is done
                        //	or we need to assign an arbitrary probe ID to those faces
                        if (MissingProbeIDFaces.Count > 0)
                        {
                            FacesWithoutProbeCount += MissingProbeIDFaces.Count;
                            PrimitivesWithoutProbeCount++;

                            // TODO: Assign nearest probe or something!
                        }

                        // Now that we have valid probe IDs for each face, propagate best probe influence to each vertex
                        ProbeInfluence[] BestProbePerVertex = new ProbeInfluence[P.m_Vertices.Length];
                        for (int FaceIndex = 0; FaceIndex < FacesCount; FaceIndex++)
                        {
                            GCXFormat.Scene.Mesh.Primitive.Face Face = P.m_Faces[FaceIndex];
                            ProbeInfluence FaceProbe = P.m_WingedEdgeFaces[FaceIndex].m_Tag as ProbeInfluence;

                            if (BestProbePerVertex[Face.V0] == null || BestProbePerVertex[Face.V0].Importance < FaceProbe.Importance)
                            {
                                BestProbePerVertex[Face.V0] = FaceProbe;                                                                                                                                                // Better probe for that vertex
                            }
                            if (BestProbePerVertex[Face.V1] == null || BestProbePerVertex[Face.V1].Importance < FaceProbe.Importance)
                            {
                                BestProbePerVertex[Face.V1] = FaceProbe;                                                                                                                                                // Better probe for that vertex
                            }
                            if (BestProbePerVertex[Face.V2] == null || BestProbePerVertex[Face.V2].Importance < FaceProbe.Importance)
                            {
                                BestProbePerVertex[Face.V2] = FaceProbe;                                                                                                                                                // Better probe for that vertex
                            }
                        }

                        // Finally, we can splat probe IDs into the giant vertex stream
                        for (int VertexIndex = 0; VertexIndex < P.m_Vertices.Length; VertexIndex++)
                        {
                            VertexStreamProbeID[P.m_VertexOffset + VertexIndex] = (UInt32)(BestProbePerVertex[VertexIndex] != null ? BestProbePerVertex[VertexIndex].ProbeID : 0xFFFFFFFF);                             // TODO <= warn if we still have invalid vertices!
                        }
                    }

                    MeshIndex++;
                }

                progressBarBatchConvert.Value = progressBarBatchConvert.Maximum;


                //////////////////////////////////////////////////////////////////////////
                // Save the final vertex stream to disk
                FileInfo TargetVertexStreamFile = new FileInfo(Path.Combine(Path.GetDirectoryName(SceneFile.FullName), Path.GetFileNameWithoutExtension(SceneFile.FullName) + "_ProbeID.vertexStream.U16"));

                using (FileStream S = TargetVertexStreamFile.Create())
                    using (BinaryWriter W = new BinaryWriter(S))
                    {
                        for (int VertexIndex = 0; VertexIndex < VertexStreamProbeID.Length; VertexIndex++)
                        {
                            W.Write(VertexStreamProbeID[VertexIndex]);
                        }
                    }

                // Notify
                MessageBoxIcon Icon = MessageBoxIcon.Information;
                string         Info = "Success!\r\n";
                Info += "Processed " + PrimitivesCount + " primitives for a total of " + GCX.m_TotalFacesCount + " faces and " + GCX.m_TotalVerticesCount + " vertices.\r\n";
                if (PrimitivesWithoutProbeCount > 0)
                {
                    Icon  = MessageBoxIcon.Warning;
                    Info += "\r\n---------------------- WARNING ----------------------\r\n";
                    Info += PrimitivesWithoutProbeCount + " primitives are missing or have incomplete probe information.\r\n";
                    Info += "A total of " + FacesWithoutProbeCount + " faces don't have probe information!\r\n";
                }
                if (Errors != "")
                {
                    Icon  = MessageBoxIcon.Warning;
                    Info += "\r\n---------------------- ERRORS ----------------------\r\n";
                    Info += Errors;
                }
                MessageBox(Info, MessageBoxButtons.OK, Icon);
            }
            catch (Exception _e)
            {
                MessageBox("An error occurred while probe influences in scene file: " + _e.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            finally
            {
                progressBarBatchConvert.Visible = false;
                progressBarSubTask.Visible      = false;
            }
        }
Ejemplo n.º 3
0
        private void batchEncodeToolStripMenuItem_Click( object sender, EventArgs e )
        {
            // Ask where to load
            string	OldFolder = GetRegKey( "LastProbesFolderSource", Path.GetDirectoryName( m_ApplicationPath ) );
            folderBrowserDialog.SelectedPath = OldFolder;
            if ( folderBrowserDialog.ShowDialog( this ) != DialogResult.OK )
                return;
            SetRegKey( "LastProbesFolderSource", folderBrowserDialog.SelectedPath );

            DirectoryInfo	SourceDir = new DirectoryInfo( folderBrowserDialog.SelectedPath );

            // Ask where to save
            OldFolder = GetRegKey( "LastProbesFolderTarget", Path.GetDirectoryName( m_ApplicationPath ) );
            folderBrowserDialog.SelectedPath = OldFolder;
            if ( folderBrowserDialog.ShowDialog( this ) != DialogResult.OK )
                return;
            SetRegKey( "LastProbesFolderTarget", folderBrowserDialog.SelectedPath );

            DirectoryInfo	TargetDir = new DirectoryInfo( folderBrowserDialog.SelectedPath );

            // Batch process!
            progressBarBatchConvert.Value = 0;
            progressBarBatchConvert.Visible = true;

            uint	MaxFaceIndex = 0;
            Dictionary<UInt32,ProbeInfluence>	BestProbeInfluencePerFace = new Dictionary<UInt32,ProbeInfluence>();

            string			Errors = null;
            int				ProcessedProbesCount = 0;
            List<FileInfo>	PomFiles = new List<FileInfo>( SourceDir.GetFiles( "*.pom" ) );
            int				OriginalFilesCount = PomFiles.Count;
            while ( PomFiles.Count > 0 )
            {
                try
                {
                    FileInfo	F = PomFiles[0];

                    PomFiles.Remove( F );

                    LoadCubeMap( F );

                    // Create probe sets
                    buttonComputeFilling_Click( null, EventArgs.Empty );

                    // Save result
                    string		TargetFileName = Path.GetFileNameWithoutExtension( F.FullName ) + ".probeset";
                    FileInfo	TargetFile = new FileInfo( Path.Combine( TargetDir.FullName, TargetFileName ) );
                    m_Probe.SaveSets( TargetFile );

                    // Process probe influences and keep the best ones for each face
                    MaxFaceIndex = Math.Max( MaxFaceIndex, m_Probe.m_MaxFaceIndex );
                    foreach ( uint FaceIndex in m_Probe.m_ProbeInfluencePerFace.Keys )
                    {
                        double	ProbeImportance = m_Probe.m_ProbeInfluencePerFace[FaceIndex];
                        if ( !BestProbeInfluencePerFace.ContainsKey( FaceIndex ) )
                        {	// Use this probe
                            BestProbeInfluencePerFace[FaceIndex] = new ProbeInfluence() { Importance=ProbeImportance, ProbeID=(UInt32) m_Probe.m_ProbeID };
                            continue;
                        }

                        double	ExistingImportance = BestProbeInfluencePerFace[FaceIndex].Importance;
                        if ( ExistingImportance >= ProbeImportance )
                            continue;

                        // We have a better probe
                        BestProbeInfluencePerFace[FaceIndex].ProbeID = (UInt32) m_Probe.m_ProbeID;
                        BestProbeInfluencePerFace[FaceIndex].Importance = ProbeImportance;
                    }

                    // Update UI
                    ProcessedProbesCount++;
                    progressBarBatchConvert.Value = progressBarBatchConvert.Maximum * (OriginalFilesCount - PomFiles.Count) / OriginalFilesCount;
                    progressBarBatchConvert.Refresh();
                    outputPanel1.Refresh();
                    textBoxResults.Refresh();
                }
                catch ( Exception _e )
                {
                    Errors += _e.Message + "\r\n";
                }
            }

            // Save the final probe influences
            FileInfo	TargetInfluenceFile = new FileInfo( Path.Combine( TargetDir.FullName, "ProbeInfluence.pim" ) );
            using ( FileStream S = TargetInfluenceFile.Create() )
                using( BinaryWriter Writer = new BinaryWriter( S ) )
                    for ( uint FaceIndex=0; FaceIndex < MaxFaceIndex; FaceIndex++ )
                    {
                        if ( BestProbeInfluencePerFace.ContainsKey( FaceIndex ) )
                        {
                            ProbeInfluence	Influence = BestProbeInfluencePerFace[FaceIndex];
                            Writer.Write( Influence.ProbeID );
                            Writer.Write( Influence.Importance );
                        }
                        else
                        {
                            Writer.Write( (int) -1 );
                            Writer.Write( 0.0 );
                        }
                    }

            // Notify
            progressBarBatchConvert.Value = progressBarBatchConvert.Maximum;
            if ( Errors == null )
                MessageBox( "Success! " + ProcessedProbesCount + " probes were processed...", MessageBoxButtons.OK, MessageBoxIcon.Information );
            else
                MessageBox( ProcessedProbesCount + " probes were processed but errors were found:\r\n\r\n" + Errors, MessageBoxButtons.OK, MessageBoxIcon.Warning );

            progressBarBatchConvert.Visible = false;
        }
Ejemplo n.º 4
0
        private void batchEncodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Ask where to load
            string OldFolder = GetRegKey("LastProbesFolderSource", Path.GetDirectoryName(m_ApplicationPath));

            folderBrowserDialog.SelectedPath = OldFolder;
            if (folderBrowserDialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }
            SetRegKey("LastProbesFolderSource", folderBrowserDialog.SelectedPath);

            DirectoryInfo SourceDir = new DirectoryInfo(folderBrowserDialog.SelectedPath);

            // Ask where to save
            OldFolder = GetRegKey("LastProbesFolderTarget", Path.GetDirectoryName(m_ApplicationPath));
            folderBrowserDialog.SelectedPath = OldFolder;
            if (folderBrowserDialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }
            SetRegKey("LastProbesFolderTarget", folderBrowserDialog.SelectedPath);

            DirectoryInfo TargetDir = new DirectoryInfo(folderBrowserDialog.SelectedPath);

            // Batch process!
            progressBarBatchConvert.Value   = 0;
            progressBarBatchConvert.Visible = true;

            uint MaxFaceIndex = 0;
            Dictionary <UInt32, ProbeInfluence> BestProbeInfluencePerFace = new Dictionary <UInt32, ProbeInfluence>();

            string          Errors = null;
            int             ProcessedProbesCount = 0;
            List <FileInfo> PomFiles             = new List <FileInfo>(SourceDir.GetFiles("*.pom"));
            int             OriginalFilesCount   = PomFiles.Count;

            while (PomFiles.Count > 0)
            {
                try
                {
                    FileInfo F = PomFiles[0];

                    PomFiles.Remove(F);

                    LoadCubeMap(F);

                    // Create probe sets
                    buttonComputeFilling_Click(null, EventArgs.Empty);

                    // Save result
                    string   TargetFileName = Path.GetFileNameWithoutExtension(F.FullName) + ".probeset";
                    FileInfo TargetFile     = new FileInfo(Path.Combine(TargetDir.FullName, TargetFileName));
                    m_Probe.SaveSets(TargetFile);

                    // Process probe influences and keep the best ones for each face
                    MaxFaceIndex = Math.Max(MaxFaceIndex, m_Probe.m_MaxFaceIndex);
                    foreach (uint FaceIndex in m_Probe.m_ProbeInfluencePerFace.Keys)
                    {
                        double ProbeImportance = m_Probe.m_ProbeInfluencePerFace[FaceIndex];
                        if (!BestProbeInfluencePerFace.ContainsKey(FaceIndex))
                        {                               // Use this probe
                            BestProbeInfluencePerFace[FaceIndex] = new ProbeInfluence()
                            {
                                Importance = ProbeImportance, ProbeID = (UInt32)m_Probe.m_ProbeID
                            };
                            continue;
                        }

                        double ExistingImportance = BestProbeInfluencePerFace[FaceIndex].Importance;
                        if (ExistingImportance >= ProbeImportance)
                        {
                            continue;
                        }

                        // We have a better probe
                        BestProbeInfluencePerFace[FaceIndex].ProbeID    = (UInt32)m_Probe.m_ProbeID;
                        BestProbeInfluencePerFace[FaceIndex].Importance = ProbeImportance;
                    }

                    // Update UI
                    ProcessedProbesCount++;
                    progressBarBatchConvert.Value = progressBarBatchConvert.Maximum * (OriginalFilesCount - PomFiles.Count) / OriginalFilesCount;
                    progressBarBatchConvert.Refresh();
                    outputPanel1.Refresh();
                    textBoxResults.Refresh();
                }
                catch (Exception _e)
                {
                    Errors += _e.Message + "\r\n";
                }
            }

            // Save the final probe influences
            FileInfo TargetInfluenceFile = new FileInfo(Path.Combine(TargetDir.FullName, "ProbeInfluence.pim"));

            using (FileStream S = TargetInfluenceFile.Create())
                using (BinaryWriter Writer = new BinaryWriter(S))
                    for (uint FaceIndex = 0; FaceIndex < MaxFaceIndex; FaceIndex++)
                    {
                        if (BestProbeInfluencePerFace.ContainsKey(FaceIndex))
                        {
                            ProbeInfluence Influence = BestProbeInfluencePerFace[FaceIndex];
                            Writer.Write(Influence.ProbeID);
                            Writer.Write(Influence.Importance);
                        }
                        else
                        {
                            Writer.Write((int)-1);
                            Writer.Write(0.0);
                        }
                    }

            // Notify
            progressBarBatchConvert.Value = progressBarBatchConvert.Maximum;
            if (Errors == null)
            {
                MessageBox("Success! " + ProcessedProbesCount + " probes were processed...", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox(ProcessedProbesCount + " probes were processed but errors were found:\r\n\r\n" + Errors, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            progressBarBatchConvert.Visible = false;
        }