Ejemplo n.º 1
0
 public void             Combine(AABB a, AABB b)
 {
     m_Min = a.m_Min;
     m_Min.Min(b.m_Min);
     m_Max = a.m_Max;
     m_Max.Max(b.m_Max);
 }
Ejemplo n.º 2
0
            public Mesh(Scene _Owner, idTech5Map.Map.Entity _Entity) : base(_Owner, _Entity)
            {
                // BUild primitives and local space BBox
                m_Primitives    = new Primitive[_Entity.m_Model.m_Surfaces.Length];
                m_BBoxMin_Local = float.MaxValue * float3.One;
                m_BBoxMax_Local = -float.MaxValue * float3.One;

                int PrimitiveIndex = 0;

                foreach (idTech5Map.Model.Surface S in _Entity.m_Model.m_Surfaces)
                {
                    m_Primitives[PrimitiveIndex] = new Primitive(this, S);
                    m_BBoxMin_Local.Min(m_Primitives[PrimitiveIndex].m_BBoxMin);
                    m_BBoxMax_Local.Max(m_Primitives[PrimitiveIndex].m_BBoxMax);
                    PrimitiveIndex++;
                }

                // Convert BBox to world space
                m_BBoxMin_World = float.MaxValue * float3.One;
                m_BBoxMax_World = -float.MaxValue * float3.One;
                for (int CornerIndex = 0; CornerIndex < 8; CornerIndex++)
                {
                    float  X = (CornerIndex >> 0) & 1;
                    float  Y = (CornerIndex >> 0) & 1;
                    float  Z = (CornerIndex >> 0) & 1;
                    float3 D = m_BBoxMax_Local - m_BBoxMin_Local;

                    float3 lsCorner = m_BBoxMin_Local + new float3(X * D.x, Y * D.y, Z * D.z);
                    float3 wsCorner = (float3)(new float4(lsCorner, 1.0f) * m_Local2Parent);

                    m_BBoxMin_World.Min(wsCorner);
                    m_BBoxMax_World.Max(wsCorner);
                }
            }
Ejemplo n.º 3
0
            /// <summary>
            /// Inserts an AABB in the tree, ensuring leaf-containing tree cells have at most the minimum dimension of the AABB
            /// </summary>
            /// <param name="_Min">The minimum corner of the AABB</param>
            /// <param name="_Max">The maximum corner of the AABB</param>
            /// <returns></returns>
            internal void           InsertAABB(float3 _Min, float3 _Max)
            {
                float3 Dim     = _Max - _Min;
                float  MinSize = Dim.Min();

                if (m_Size < MinSize || m_Size <= MIN_CELL_SIZE)
                {
                    return;                     // This cell is already too small
                }
                // Recurse through children
                float  ChildSize = 0.5f * m_Size;
                float3 P;

                for (int Z = 0; Z < 2; Z++)
                {
                    P.z = m_Min.z + Z * ChildSize;
                    float nz = P.z + ChildSize;
                    if (_Min.z >= nz || _Max.z < P.z)
                    {
                        continue;                               // Easy early out
                    }
                    for (int Y = 0; Y < 2; Y++)
                    {
                        P.y = m_Min.y + Y * ChildSize;
                        float ny = P.y + ChildSize;
                        if (_Min.y >= ny || _Max.y < P.y)
                        {
                            continue;                                   // Easy early out
                        }
                        for (int X = 0; X < 2; X++)
                        {
                            P.x = m_Min.x + X * ChildSize;
                            float nx = P.x + ChildSize;
                            if (_Min.x >= nx || _Max.x < P.x)
                            {
                                continue;                                       // Easy early out
                            }
                            if (m_Children[X, Y, Z] == null)
                            {                                   // Create the child
                                Cell Child = new Cell()
                                {
                                    m_Parent = this,
                                    m_Min    = P,
                                    m_Size   = ChildSize,
                                };
                                m_Children[X, Y, Z] = Child;
                            }

                            // Recurse
                            m_Children[X, Y, Z].InsertAABB(_Min, _Max);
                        }
                    }
                }
            }
Ejemplo n.º 4
0
        void TestSHRGBEEncoding()
        {
            float3[] coeffs = null;

            System.IO.FileInfo coeffsFileName = new System.IO.FileInfo("SHCoeffs.sh3");
            using (System.IO.FileStream S = coeffsFileName.OpenRead())
                using (System.IO.BinaryReader R = new System.IO.BinaryReader(S)) {
                    uint coeffsCount = R.ReadUInt32();
                    coeffs = new float3[coeffsCount * 9];
                    for (int i = 0; i < 9 * coeffsCount; i++)
                    {
                        coeffs[i] = new float3(R.ReadSingle(), R.ReadSingle(), R.ReadSingle());

// The exponent bias allows us to support up to 512 in luminance!
//coeffs[i] *= 5.0f;
                    }
                }

            uint   test1_packed   = EncodeRGBE(new float3(1, 0, 1.5f));
            float3 test1_unpacked = DecodeRGBE(test1_packed);

//			float3	coeffMin = new float3( float.MaxValue, float.MaxValue, float.MaxValue );
            float3 coeffMax    = new float3(-float.MaxValue, -float.MaxValue, -float.MaxValue);
            float3 coeffMinAbs = new float3(float.MaxValue, float.MaxValue, float.MaxValue);
            int    coeffsWithDifferentSignsInRGBCount = 0;

            for (int i = 0; i < coeffs.Length; i++)
            {
                float3 coeff    = coeffs[i];
                float3 absCoeff = new float3(Math.Abs(coeff.x), Math.Abs(coeff.y), Math.Abs(coeff.z));

                if (coeff.x * coeff.y < 0.0f || coeff.x * coeff.z < 0.0f || coeff.y * coeff.z < 0.0f)
                {
                    coeffsWithDifferentSignsInRGBCount++;
                }

//				coeffMin.Min( coeff );
                coeffMax.Max(absCoeff);
                if (absCoeff.x > 0.0f)
                {
                    coeffMinAbs.x = Math.Min(coeffMinAbs.x, absCoeff.x);
                }
                if (absCoeff.y > 0.0f)
                {
                    coeffMinAbs.y = Math.Min(coeffMinAbs.y, absCoeff.y);
                }
                if (absCoeff.z > 0.0f)
                {
                    coeffMinAbs.z = Math.Min(coeffMinAbs.z, absCoeff.z);
                }
            }

            double expMin = Math.Min(Math.Min(Math.Log(coeffMinAbs.x) / Math.Log(2), Math.Log(coeffMinAbs.y) / Math.Log(2)), Math.Log(coeffMinAbs.z) / Math.Log(2));
            double expMax = Math.Max(Math.Max(Math.Log(coeffMax.x) / Math.Log(2), Math.Log(coeffMax.y) / Math.Log(2)), Math.Log(coeffMax.z) / Math.Log(2));

            // Measure discrepancies after RGBE encoding
//          float3	errorAbsMin = new float3( +float.MaxValue, +float.MaxValue, +float.MaxValue );
//          float3	errorAbsMax = new float3( -float.MaxValue, -float.MaxValue, -float.MaxValue );
            float3 errorRelMin = new float3(+float.MaxValue, +float.MaxValue, +float.MaxValue);
            float3 errorRelMax = new float3(-float.MaxValue, -float.MaxValue, -float.MaxValue);
            int    minExponent = +int.MaxValue, maxExponent = -int.MaxValue;
            int    largeRelativeErrorsCount = 0;

            for (int i = 0; i < coeffs.Length; i++)
            {
                float3 originalRGB = coeffs[i];
                uint   RGBE        = EncodeRGBE(originalRGB);
                float3 decodedRGB  = DecodeRGBE(RGBE);

                // Compute absolute error
//              float3	delta = decodedRGB - originalRGB;
//              float3	distanceFromOriginal = new float3( Math.Abs( delta.x ), Math.Abs( delta.y ), Math.Abs( delta.z ) );
//              errorAbsMin.Min( distanceFromOriginal );
//              errorAbsMax.Max( distanceFromOriginal );

                // Compute relative error
                float3 errorRel = new float3(Math.Abs(originalRGB.x) > 0.0f ? Math.Abs(decodedRGB.x / originalRGB.x - 1.0f) : 0.0f, Math.Abs(originalRGB.y) > 0.0f ? Math.Abs(decodedRGB.y / originalRGB.y - 1.0f) : 0.0f, Math.Abs(originalRGB.z) > 0.0f ? Math.Abs(decodedRGB.z / originalRGB.z - 1.0f) : 0.0f);

                // Scale the relative error by the magnitude of each component as compared to the maximum component
                // This way, if we happen to have a "large" relative error on a component that is super small compared to the component with maximum amplitude then we can safely drop that small component (it's insignificant compared to the largest contribution)
                float  maxComponent   = Math.Max(Math.Max(Math.Abs(originalRGB.x), Math.Abs(originalRGB.y)), Math.Abs(originalRGB.z));
                float3 magnitudeScale = maxComponent > 0.0f ? new float3(Math.Abs(originalRGB.x) / maxComponent, Math.Abs(originalRGB.y) / maxComponent, Math.Abs(originalRGB.z) / maxComponent) : float3.Zero;
                errorRel *= magnitudeScale;

                // Don't account for dernomalization
//              if ( decodedRGB.x == 0.0 && originalRGB.x != 0.0f ) errorRel.x = 0.0f;
//              if ( decodedRGB.y == 0.0 && originalRGB.y != 0.0f ) errorRel.y = 0.0f;
//              if ( decodedRGB.z == 0.0 && originalRGB.z != 0.0f ) errorRel.z = 0.0f;

                const float errorThreshold = 0.2f;
                if (Math.Abs(errorRel.x) > errorThreshold || Math.Abs(errorRel.y) > errorThreshold || Math.Abs(errorRel.z) > errorThreshold)
                {
                    largeRelativeErrorsCount++;
                }
                errorRelMin.Min(errorRel);
                errorRelMax.Max(errorRel);

                int exp = (int)((RGBE >> 24) & 31) - EXPONENT_BIAS;
                minExponent = Math.Min(minExponent, exp);
                maxExponent = Math.Max(maxExponent, exp);
            }
        }
Ejemplo n.º 5
0
                public Primitive(Mesh _Owner, FBX.Scene.Nodes.Mesh.Primitive _Primitive)
                {
                    m_Owner = _Owner;

                    m_MaterialID = (ushort)_Primitive.MaterialParms.ID;

                    m_Faces    = new Face[_Primitive.FacesCount];
                    m_Vertices = new Vertex[_Primitive.VerticesCount];

                    // Retrieve streams
                    FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE[] Usages =
                    {
                        FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.POSITION,
                        FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.NORMAL,
                        FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TANGENT,
                        FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.BITANGENT,
                        FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS,
                    };
                    FBX.Scene.Nodes.Mesh.Primitive.VertexStream[][] Streams = new FBX.Scene.Nodes.Mesh.Primitive.VertexStream[Usages.Length][];
                    for (int UsageIndex = 0; UsageIndex < Usages.Length; UsageIndex++)
                    {
                        Streams[UsageIndex] = _Primitive.FindStreamsByUsage(Usages[UsageIndex]);
                        if (Streams[UsageIndex].Length == 0)
                        {
                            throw new Exception("No stream for usage " + Usages[UsageIndex] + "! Can't complete target vertex format!");
                        }
                    }

                    // Build local space bounding box
                    float3 Temp = new float3();

                    WMath.Vector[] VertexPositions = Streams[0][0].Content as WMath.Vector[];
                    foreach (WMath.Vector VertexPosition in VertexPositions)
                    {
                        Temp.FromVector3(VertexPosition);
                        m_BBoxMin.Min(Temp);
                        m_BBoxMax.Max(Temp);
                    }

                    // Build faces
                    int FaceIndex = 0;

                    foreach (FBX.Scene.Nodes.Mesh.Primitive.Face F in _Primitive.Faces)
                    {
                        m_Faces[FaceIndex].V0 = F.V0;
                        m_Faces[FaceIndex].V1 = F.V1;
                        m_Faces[FaceIndex].V2 = F.V2;
                        FaceIndex++;
                    }

                    // Build vertices
                    for (int VertexIndex = 0; VertexIndex < m_Vertices.Length; VertexIndex++)
                    {
                        for (int UsageIndex = 0; UsageIndex < Usages.Length; UsageIndex++)
                        {
                            FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE Usage = Usages[UsageIndex];
                            switch (Usage)
                            {
                            case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.POSITION:
                            {
                                float3[] Stream = Streams[UsageIndex][0].Content as float3[];
                                m_Vertices[VertexIndex].P = Stream[VertexIndex];
                                break;
                            }

                            case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.NORMAL:
                            {
                                float3[] Stream = Streams[UsageIndex][0].Content as float3[];
                                m_Vertices[VertexIndex].N = Stream[VertexIndex];
                                break;
                            }

                            case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TANGENT:
                            {
                                float3[] Stream = Streams[UsageIndex][0].Content as float3[];
                                m_Vertices[VertexIndex].G = Stream[VertexIndex];
                                break;
                            }

                            case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.BITANGENT:
                            {
                                float3[] Stream = Streams[UsageIndex][0].Content as float3[];
                                m_Vertices[VertexIndex].B = Stream[VertexIndex];
                                break;
                            }

                            case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS:
                            {
                                float2[] Stream = Streams[UsageIndex][0].Content as float2[];
                                m_Vertices[VertexIndex].T = Stream[VertexIndex];
                                break;
                            }
                            }
                        }
                    }
                }
Ejemplo n.º 6
0
 public void             Combine(AABB _Other)
 {
     m_Min.Min(_Other.m_Min);
     m_Max.Max(_Other.m_Max);
 }
Ejemplo n.º 7
0
        void TestSHRGBEEncoding()
        {
            float3[]	coeffs = null;

            System.IO.FileInfo	coeffsFileName = new System.IO.FileInfo( "SHCoeffs.sh3" );
            using ( System.IO.FileStream S = coeffsFileName.OpenRead() )
                using ( System.IO.BinaryReader R = new System.IO.BinaryReader( S ) ) {
                    uint	coeffsCount = R.ReadUInt32();
                    coeffs = new float3[coeffsCount * 9];
                    for ( int i=0; i < 9*coeffsCount; i++ ) {
                        coeffs[i] = new float3( R.ReadSingle(), R.ReadSingle(), R.ReadSingle() );

            // The exponent bias allows us to support up to 512 in luminance!
            //coeffs[i] *= 5.0f;

                    }
                }

            uint	test1_packed = EncodeRGBE( new float3( 1, 0, 1.5f ) );
            float3	test1_unpacked = DecodeRGBE( test1_packed );

            //			float3	coeffMin = new float3( float.MaxValue, float.MaxValue, float.MaxValue );
            float3	coeffMax = new float3( -float.MaxValue, -float.MaxValue, -float.MaxValue );
            float3	coeffMinAbs = new float3( float.MaxValue, float.MaxValue, float.MaxValue );
            int		coeffsWithDifferentSignsInRGBCount = 0;
            for ( int i=0; i < coeffs.Length; i++ ) {
                float3	coeff = coeffs[i];
                float3	absCoeff = new float3( Math.Abs( coeff.x ), Math.Abs( coeff.y ), Math.Abs( coeff.z ) );

                if ( coeff.x * coeff.y < 0.0f || coeff.x * coeff.z < 0.0f || coeff.y * coeff.z < 0.0f )
                    coeffsWithDifferentSignsInRGBCount++;

            //				coeffMin.Min( coeff );
                coeffMax.Max( absCoeff );
                if ( absCoeff.x > 0.0f ) coeffMinAbs.x = Math.Min( coeffMinAbs.x, absCoeff.x );
                if ( absCoeff.y > 0.0f ) coeffMinAbs.y = Math.Min( coeffMinAbs.y, absCoeff.y );
                if ( absCoeff.z > 0.0f ) coeffMinAbs.z = Math.Min( coeffMinAbs.z, absCoeff.z );
            }

            double	expMin = Math.Min( Math.Min( Math.Log( coeffMinAbs.x ) / Math.Log(2), Math.Log( coeffMinAbs.y ) / Math.Log(2) ), Math.Log( coeffMinAbs.z ) / Math.Log(2) );
            double	expMax = Math.Max( Math.Max( Math.Log( coeffMax.x ) / Math.Log(2), Math.Log( coeffMax.y ) / Math.Log(2) ), Math.Log( coeffMax.z ) / Math.Log(2) );

            // Measure discrepancies after RGBE encoding
            // 			float3	errorAbsMin = new float3( +float.MaxValue, +float.MaxValue, +float.MaxValue );
            // 			float3	errorAbsMax = new float3( -float.MaxValue, -float.MaxValue, -float.MaxValue );
            float3	errorRelMin = new float3( +float.MaxValue, +float.MaxValue, +float.MaxValue );
            float3	errorRelMax = new float3( -float.MaxValue, -float.MaxValue, -float.MaxValue );
            int		minExponent = +int.MaxValue, maxExponent = -int.MaxValue;
            int		largeRelativeErrorsCount = 0;
            for ( int i=0; i < coeffs.Length; i++ ) {
                float3	originalRGB = coeffs[i];
                uint	RGBE = EncodeRGBE( originalRGB );
                float3	decodedRGB = DecodeRGBE( RGBE );

                // Compute absolute error
            // 				float3	delta = decodedRGB - originalRGB;
            // 				float3	distanceFromOriginal = new float3( Math.Abs( delta.x ), Math.Abs( delta.y ), Math.Abs( delta.z ) );
            // 				errorAbsMin.Min( distanceFromOriginal );
            // 				errorAbsMax.Max( distanceFromOriginal );

                // Compute relative error
                float3	errorRel = new float3( Math.Abs( originalRGB.x ) > 0.0f ? Math.Abs( decodedRGB.x / originalRGB.x - 1.0f ) : 0.0f, Math.Abs( originalRGB.y ) > 0.0f ? Math.Abs( decodedRGB.y / originalRGB.y - 1.0f ) : 0.0f, Math.Abs( originalRGB.z ) > 0.0f ? Math.Abs( decodedRGB.z / originalRGB.z - 1.0f ) : 0.0f );

                // Scale the relative error by the magnitude of each component as compared to the maximum component
                // This way, if we happen to have a "large" relative error on a component that is super small compared to the component with maximum amplitude then we can safely drop that small component (it's insignificant compared to the largest contribution)
                float	maxComponent = Math.Max( Math.Max( Math.Abs( originalRGB.x ), Math.Abs( originalRGB.y ) ), Math.Abs( originalRGB.z ) );
                float3	magnitudeScale = maxComponent > 0.0f ? new float3( Math.Abs( originalRGB.x ) / maxComponent, Math.Abs( originalRGB.y ) / maxComponent, Math.Abs( originalRGB.z ) / maxComponent ) : float3.Zero;
                errorRel *= magnitudeScale;

                // Don't account for dernomalization
            // 				if ( decodedRGB.x == 0.0 && originalRGB.x != 0.0f ) errorRel.x = 0.0f;
            // 				if ( decodedRGB.y == 0.0 && originalRGB.y != 0.0f ) errorRel.y = 0.0f;
            // 				if ( decodedRGB.z == 0.0 && originalRGB.z != 0.0f ) errorRel.z = 0.0f;

                const float	errorThreshold = 0.2f;
                if ( Math.Abs( errorRel.x ) > errorThreshold || Math.Abs( errorRel.y ) > errorThreshold || Math.Abs( errorRel.z ) > errorThreshold )
                    largeRelativeErrorsCount++;
                errorRelMin.Min( errorRel );
                errorRelMax.Max( errorRel );

                int		exp = (int) ((RGBE >> 24) & 31) - EXPONENT_BIAS;
                minExponent = Math.Min( minExponent, exp );
                maxExponent = Math.Max( maxExponent, exp );
            }
        }
Ejemplo n.º 8
0
 public void Combine( AABB a, AABB b )
 {
     m_Min = a.m_Min;
     m_Min.Min( b.m_Min );
     m_Max = a.m_Max;
     m_Max.Max( b.m_Max );
 }
Ejemplo n.º 9
0
            public Mesh( Scene _Owner, idTech5Map.Map.Entity _Entity )
                : base(_Owner, _Entity)
            {
                // BUild primitives and local space BBox
                m_Primitives = new Primitive[_Entity.m_Model.m_Surfaces.Length];
                m_BBoxMin_Local = float.MaxValue * float3.One;
                m_BBoxMax_Local = -float.MaxValue * float3.One;

                int	PrimitiveIndex = 0;
                foreach ( idTech5Map.Model.Surface S in _Entity.m_Model.m_Surfaces ) {
                    m_Primitives[PrimitiveIndex] = new Primitive( this, S );
                    m_BBoxMin_Local.Min( m_Primitives[PrimitiveIndex].m_BBoxMin );
                    m_BBoxMax_Local.Max( m_Primitives[PrimitiveIndex].m_BBoxMax );
                    PrimitiveIndex++;
                }

                // Convert BBox to world space
                m_BBoxMin_World = float.MaxValue * float3.One;
                m_BBoxMax_World = -float.MaxValue * float3.One;
                for ( int CornerIndex=0; CornerIndex < 8; CornerIndex++ ) {
                    float	X = (CornerIndex >> 0) & 1;
                    float	Y = (CornerIndex >> 0) & 1;
                    float	Z = (CornerIndex >> 0) & 1;
                    float3	D = m_BBoxMax_Local - m_BBoxMin_Local;

                    float3	lsCorner = m_BBoxMin_Local + new float3( X * D.x, Y * D.y, Z * D.z );
                    float3	wsCorner = (float3) (new float4( lsCorner, 1.0f ) * m_Local2Parent);

                    m_BBoxMin_World.Min( wsCorner );
                    m_BBoxMax_World.Max( wsCorner );
                }
            }