void Sphere::MakeBound( Bound &out_bound ) const { float tuMin = mThetamaxRad * mURange[0]; float tuMax = mThetamaxRad * mURange[1]; float alphaMin = DASin( mZMin / mRadius ); float alphaMax = DASin( mZMax / mRadius ); float aVMin = DMix( alphaMin, alphaMax, mVRange[0] ); float aVMax = DMix( alphaMin, alphaMax, mVRange[1] ); float rVMin = DCos( aVMin ) * mRadius; float rVMax = DCos( aVMax ) * mRadius; float rMin = DMIN( rVMin, rVMax ); float rMax; if ( aVMin < 0 && aVMax > 0 ) rMax = mRadius; else rMax = DMAX( rVMin, rVMax ); out_bound.Reset(); bounds2DSweepL( out_bound, rMin, rMax, tuMin, tuMax ); out_bound.mBox[0].z() = DSin( aVMin ) * mRadius; out_bound.mBox[1].z() = DSin( aVMax ) * mRadius; }
//================================================================== void Cylinder::MakeBound( Bound &out_bound ) const { float tuMin = mThetamaxRad * mURange[0]; float tuMax = mThetamaxRad * mURange[1]; out_bound.Reset(); bounds2DSweepL( out_bound, mRadius, mRadius, tuMin, tuMax ); out_bound.mBox[0].z() = DMix( mZMin, mZMax, mVRange[0] ); out_bound.mBox[1].z() = DMix( mZMin, mZMax, mVRange[1] ); }
void Torus::MakeBound( Bound &out_bound ) const { float tuMin = mThetamaxRad * mURange[0]; float tuMax = mThetamaxRad * mURange[1]; float phiVMin = DMix( mPhiminRad, mPhimaxRad, mVRange[0] ); float phiVMax = DMix( mPhiminRad, mPhimaxRad, mVRange[1] ); Bound a; a.Reset(); bounds2DSweepR( a, mMinRadius, phiVMin, phiVMax ); float rMin = a.mBox[0].x() + mMaxRadius; float rMax = a.mBox[1].x() + mMaxRadius; out_bound.Reset(); bounds2DSweepL( out_bound, rMin, rMax, tuMin, tuMax ); out_bound.mBox[0].z() = a.mBox[0].y(); out_bound.mBox[1].z() = a.mBox[1].y(); }
void Cone::MakeBound( Bound &out_bound ) const { float tuMin = mThetamaxRad * mURange[0]; float tuMax = mThetamaxRad * mURange[1]; float rMin = mRadius * (1 - mVRange[1]); float rMax = mRadius * (1 - mVRange[0]); out_bound.Reset(); bounds2DSweepL( out_bound, rMin, rMax, tuMin, tuMax ); out_bound.mBox[0].z() = mVRange[0] * mHeight; out_bound.mBox[1].z() = mVRange[1] * mHeight; }
void Paraboloid::MakeBound( Bound &out_bound ) const { float scale = mRmax / DSqrt( mZmax ); float tuMin = mThetamaxRad * mURange[0]; float tuMax = mThetamaxRad * mURange[1]; float zVMin = mZmin + mVRange[0] * (mZmax-mZmin); float zVMax = mZmin + mVRange[1] * (mZmax-mZmin); float rMin = DSqrt( zVMin ) * scale; float rMax = DSqrt( zVMax ) * scale; out_bound.Reset(); bounds2DSweepL( out_bound, rMin, rMax, tuMin, tuMax ); out_bound.mBox[0].z() = zVMin; out_bound.mBox[1].z() = zVMax; }
void Hyperboloid::MakeBound( Bound &out_bound ) const { float tuMin = mThetamaxRad * mURange[0]; float tuMax = mThetamaxRad * mURange[1]; Float2_ uvMin( 0.f, mVRange[0] ); Float2_ uvMax( 0.f, mVRange[1] ); Float3_ pMin; EvalP( uvMin, pMin ); Float3_ pMax; EvalP( uvMax, pMax ); out_bound.Reset(); bounds2DSweepP( out_bound, pMin.x()[0], pMin.y()[0], tuMin, tuMax ); bounds2DSweepP( out_bound, pMax.x()[0], pMax.y()[0], tuMin, tuMax ); out_bound.mBox[0].z() = DMIN( pMin.z()[0], pMax.z()[0] ); out_bound.mBox[1].z() = DMAX( pMin.z()[0], pMax.z()[0] ); }
//================================================================== SimplePrimitiveBase::CheckSplitRes SimplePrimitiveBase::CheckForSplit( const Hider &hider, int out_bound2d[4], bool &out_uSplit, bool &out_vSplit ) { const Matrix44 &mtxLocalWorld = mpTransform->GetMatrix(); DASSERT( mDiceGridWd == -1 && mDiceGridHe == -1 ); Float3_ testDicePo[ MAX_MAKE_BOUND_OUT_SIZE ]; Bound bound; bound.Reset(); MakeBound( bound, testDicePo ); float pixelArea = hider.RasterEstimate( bound, mtxLocalWorld, out_bound2d ); if ( pixelArea <= MP_GRID_MAX_SIZE ) { if ( pixelArea < RI_EPSILON ) { return CHECKSPLITRES_CULL; } float dim = DSqrt( pixelArea ); mDiceGridWd = DMT_SIMD_PADSIZE( (int)ceilf( dim ) ); mDiceGridHe = (int)ceilf( dim ); out_uSplit = false; out_vSplit = false; return CHECKSPLITRES_DICE; // will dice } else { #if 0 SlVec2 locUV[ TEST_DICE_SIMD_BLOCKS ]; // set last item to 0 to be safe when using the AddReduce() later on locUV[ TEST_DICE_SIMD_BLOCKS - 1 ] = SlVec2( 0.f, 0.f ); fillUVsArray( locUV, 1.0f / (TEST_DICE_LEN - 1), 1.0f / (TEST_DICE_LEN - 1), TEST_DICE_LEN, TEST_DICE_LEN ); //Float3_ avg_dPdu( 0.f, 0.f, 0.f ); //Float3_ avg_dPdv( 0.f, 0.f, 0.f ); SlScalar avg_dPdu( 0.f ); SlScalar avg_dPdv( 0.f ); for (u_int i=0; i < TEST_DICE_SIMD_BLOCKS; ++i) { SlVec3 posLS; SlVec3 dPdu; SlVec3 dPdv; Eval_dPdu_dPdv( locUV[ i ], posLS, &dPdu, &dPdv ); avg_dPdu += dPdu.GetLengthSqr(); avg_dPdv += dPdv.GetLengthSqr(); } // divide by the total number of elements //avg_dPdu /= (float)TEST_DICE_SIMD_BLOCKS * DMT_SIMD_FLEN; //avg_dPdv /= (float)TEST_DICE_SIMD_BLOCKS * DMT_SIMD_FLEN; /* Float3 avg_dPdu_s( avg_dPdu.x().AddReduce(), // avg_dPdu.x()[0] + avg_dPdu.x()[1] ... avg_dPdu.y().AddReduce(), avg_dPdu.z().AddReduce() ); Float3 avg_dPdv_s( avg_dPdv.x().AddReduce(), // avg_dPdv.x()[0] + avg_dPdv.x()[1] ... avg_dPdv.y().AddReduce(), avg_dPdv.z().AddReduce() ); */ float lenU = avg_dPdu.AddReduce(); float lenV = avg_dPdv.AddReduce(); if ( lenU < lenV ) { out_uSplit = false; out_vSplit = true; } else { out_uSplit = true; out_vSplit = false; } #else out_uSplit = true; out_vSplit = true; #endif return CHECKSPLITRES_SPLIT; // will split } }