Exemple #1
0
// Dump a pixel sample
void CqMPDump::dump(int x, int y, int idx, const CqVector2D& pos)
{
	short id = 2;
	TqFloat f;

	if (m_outFile==NULL)
	{
		Aqsis::log() << error << "Attempted to write to unopened mpdump file." << std::endl;
		return;
	}

	size_t len_written = fwrite((void*)&id, sizeof(short), 1, m_outFile);
	len_written += fwrite((void*)&x, sizeof(int), 1, m_outFile);
	len_written += fwrite((void*)&y, sizeof(int), 1, m_outFile);
	len_written += fwrite((void*)&idx, sizeof(int), 1, m_outFile);
	f = pos.x();
	len_written += fwrite((void*)&f, sizeof(TqFloat), 1, m_outFile);
	f = pos.y();
	len_written += fwrite((void*)&f, sizeof(TqFloat), 1, m_outFile);
	if(len_written != 6)
		AQSIS_THROW_XQERROR(XqInvalidFile, EqE_System,
				"Error writing mpdump file");
}
Exemple #2
0
// Dump all pixel samples of the current bucket
void CqMPDump::dumpPixelSamples(const CqBucketProcessor& bp)
{
	const std::vector<CqImagePixelPtr>& pixels = bp.pixels();
	for(std::vector<CqImagePixelPtr>::const_iterator p = pixels.begin(),
			e = pixels.end(); p != e; ++p)
	{
		const CqImagePixel& pixel = **p;
		for(int i = 0, numSamples = pixel.numSamples(); i < numSamples; ++i)
		{
			CqVector2D pos = pixel.SampleData(i).position;
			if(!(  pos.x() <= bp.SampleRegion().xMin()
				|| pos.x() > bp.SampleRegion().xMax()
				|| pos.y() <= bp.SampleRegion().yMin()
				|| pos.y() > bp.SampleRegion().yMax() ) )
			{
				// Only dump samples which are inside bp.SampleRegion()
				// this means that only samples which are actually computed for
				// the current bucket will be considered.
				dump(lfloor(pos.x()), lfloor(pos.y()), i, pos);
			}
		}
	}
}
Exemple #3
0
bool CqCurve::Diceable()
{
	// OK, here the CqCubicCurveSegment line has two options:
	//  1. split into two more lines
	//  2. turn into a bilinear patch for rendering
	// We don't want to go turning into a patch unless absolutely
	// necessary, since patches cost more.  We only want to become a patch
	// if the current curve is "best handled" as a patch.  For now, I'm
	// choosing to define that the curve is best handled as a patch under
	// one or more of the following two conditions:
	//  1. If the maximum width is a significant fraction of the length of
	//      the line (width greater than 0.75 x length; ignoring normals).
	//  2. If the length of the line (ignoring the width; cos' it's
	//      covered by point 1) is such that it's likely a bilinear
	//      patch would be diced immediately if we created one (so that
	//      patches don't have to get split!).
	//  3. If the curve crosses the eye plane (m_fDiceable == false).

	// find the length of the CqLinearCurveSegment line in raster space
	if( m_splitDecision == Split_Undecided )
	{
		// AGG - 31/07/04
		// well, if we follow the above statagy we end up splitting into
		// far too many grids (with roughly 1 mpg per grid). so after
		// profiling a few scenes, the fastest method seems to be just
		// to convert to a patch immediatly.
		// we really need a native dice for curves but until that time
		// i reckon this is best.
		//m_splitDecision = Split_Patch;

		CqMatrix matCtoR;
		QGetRenderContext() ->matSpaceToSpace(
									"camera", "raster",
									NULL, NULL,
									QGetRenderContextI()->Time(),
									matCtoR
									);
		// control hull
		CqVector2D hull[2] = {
			vectorCast<CqVector2D>(matCtoR * P()->pValue(0)[0]),
			vectorCast<CqVector2D>(matCtoR * P()->pValue(1)[0])
		};
		CqVector2D lengthVector = hull[ 1 ] - hull[ 0 ];
		TqFloat lengthraster = lengthVector.Magnitude();

		// find the approximate "length" of a diced patch in raster space
		TqFloat gridlength = GetGridLength();

		// decide whether to split into more curve segments or a patch
		if(( lengthraster < gridlength ) || ( !m_fDiceable ))
		{
			// split into a patch
			m_splitDecision = Split_Patch;
		}
		else
		{
			// split into smaller curves
			m_splitDecision = Split_Curve;
		}
	}

	return false;
}
bool CqImageBuffer::CullSurface( CqBound& Bound, const boost::shared_ptr<CqSurface>& pSurface )
{
	// If the primitive is completely outside of the hither-yon z range, cull it.
	if ( Bound.vecMin().z() >= m_optCache.clipFar ||
	     Bound.vecMax().z() <= m_optCache.clipNear )
		return true;

	// This needs to be re-enabled when the RiClippingPlane code is wired up.
#if 0
	if(QGetRenderContext()->clippingVolume().whereIs(Bound) == CqBound::Side_Outside)
	{
		return(true);
	}
#endif

	// If the primitive spans the epsilon plane and the hither plane and can be split,
	if ( Bound.vecMin().z() <= FLT_EPSILON )
	{
		// Mark the primitive as not dicable.
		pSurface->ForceUndiceable();

		CqString objname( "unnamed" );
		const CqString* pattrName = pSurface->pAttributes() ->GetStringAttribute( "identifier", "name" );
		if ( pattrName != 0 )
			objname = pattrName[ 0 ];
		Aqsis::log() << info << "Object \"" << objname.c_str() << "\" spans the epsilon plane" << std::endl;

		if ( pSurface->SplitCount() > m_optCache.maxEyeSplits )
		{
			Aqsis::log() << warning << "Max eyesplits for object \"" << objname.c_str() << "\" exceeded" << std::endl;
			return( true );
		}
		return ( false );
	}

	TqFloat minz = Bound.vecMin().z();
	TqFloat maxz = Bound.vecMax().z();


	// Convert the bounds to raster space.
	CqMatrix mat;
	QGetRenderContext() ->matSpaceToSpace( "camera", "raster", NULL, NULL, QGetRenderContext()->Time(), mat );
	Bound.Transform( mat );

	// Take into account depth-of-field
	if ( QGetRenderContext() ->UsingDepthOfField() )
	{
		const CqVector2D minZCoc = QGetRenderContext()->GetCircleOfConfusion( minz );
		const CqVector2D maxZCoc = QGetRenderContext()->GetCircleOfConfusion( maxz );
		TqFloat cocX = max( minZCoc.x(), maxZCoc.x() );
		TqFloat cocY = max( minZCoc.y(), maxZCoc.y() );
		Bound.vecMin().x( Bound.vecMin().x() - cocX );
		Bound.vecMin().y( Bound.vecMin().y() - cocY );
		Bound.vecMax().x( Bound.vecMax().x() + cocX );
		Bound.vecMax().y( Bound.vecMax().y() + cocY );
	}

	// And expand to account for filter size.
	Bound.vecMin().x( Bound.vecMin().x() - m_optCache.xFiltSize / 2.0f );
	Bound.vecMin().y( Bound.vecMin().y() - m_optCache.yFiltSize / 2.0f );
	Bound.vecMax().x( Bound.vecMax().x() + m_optCache.xFiltSize / 2.0f );
	Bound.vecMax().y( Bound.vecMax().y() + m_optCache.yFiltSize / 2.0f );

	// If the bounds are completely outside the viewing frustum, cull the primitive.
	if( Bound.vecMin().x() > QGetRenderContext()->cropWindowXMax() ||
		Bound.vecMin().y() > QGetRenderContext()->cropWindowYMax() ||
		Bound.vecMax().x() < QGetRenderContext()->cropWindowXMin() ||
		Bound.vecMax().y() < QGetRenderContext()->cropWindowYMin() )
		return ( true );

	// Restore Z-Values to camera space.
	Bound.vecMin().z( minz );
	Bound.vecMax().z( maxz );

	// Cache the Bound.
	pSurface->CacheRasterBound( Bound );
	return ( false );
}