Example #1
0
void CqTransform::ConcatCurrentTransform( TqFloat time, const CqMatrix& matTrans )
{
	TqFloat det = matTrans.Determinant();
	bool flip = ( !matTrans.fIdentity() && det < 0 );

	SqTransformation ct;
	ct.m_matTransform = matTrans;
	ct.m_Handedness = (flip)? !m_Handedness : m_Handedness;

	// If we are actually in a motion block, and we already describe a moving transform,
	// concatenate this transform with the existing one at that time slot,
	// ConcatTimeSlot will take care of making sure that the matrix is initially set to the
	// static matrix, as long as we ensure that the default is kept up to date.
	if ( QGetRenderContext() ->pconCurrent() ->fMotionBlock() )
	{
		ConcatTimeSlot( time, ct );
		m_IsMoving = true;
	}
	else
		// else, if we are moving, apply this transform at all time slots, otherwise apply to static matrix.
	{
		if( m_IsMoving )
			ConcatAllTimeSlots( ct );
		else
		{
			m_StaticMatrix = m_StaticMatrix * matTrans;
			m_Handedness = (flip)? !m_Handedness : m_Handedness;
			ct.m_Handedness = m_Handedness;
			SetDefaultObject( ct );
		}
	}
}
Example #2
0
void CqTransform::SetCurrentTransform( TqFloat time, const CqMatrix& matTrans )
{
	TqFloat det = matTrans.Determinant();
	bool flip = ( !matTrans.fIdentity() && det < 0 );

	SqTransformation ct;
	ct.m_matTransform = matTrans;
	ct.m_Handedness = !flip;

	if ( QGetRenderContext() ->pconCurrent() ->fMotionBlock() )
	{
		AddTimeSlot( time, ct );
		m_IsMoving = true;
	}
	else
	{
		if( m_IsMoving )
		{
			AddTimeSlot( time, ct );
		}
		else
		{
			m_StaticMatrix = matTrans;
			m_Handedness = (flip)? !m_Handedness : m_Handedness;
			//m_Handedness = flip;
			ct.m_Handedness = flip;
			SetDefaultObject( ct );
		}
	}
}
Example #3
0
void CqTransform::SetTransform( TqFloat time, const CqMatrix& matTrans )
{
	TqFloat det = matTrans.Determinant();
	bool flip = ( !matTrans.fIdentity() && det < 0 );
	CqMatrix matCtoW;
	QGetRenderContext()->matSpaceToSpace("world", "camera", NULL, NULL, QGetRenderContext()->Time(), matCtoW);
	TqFloat camdet = matCtoW.Determinant();
	bool camhand = ( !matCtoW.fIdentity() && camdet < 0 );

	if ( QGetRenderContext() ->pconCurrent() ->fMotionBlock() )
	{
		SqTransformation ct;
		ct.m_Handedness = (flip)? !camhand : camhand;
		ct.m_matTransform = matTrans;
		AddTimeSlot( time, ct );
		m_IsMoving = true;
	}
	else
	{
		// If not in a motion block, but we are moving, apply the transform to all keys.
		if( m_IsMoving )
		{
			CqMatrix mat0 = matObjectToWorld(Time(0));

			SqTransformation ct;
			ct.m_Handedness = (flip)? !camhand : camhand;
			bool hand0 = ct.m_Handedness;
			ct.m_matTransform = matTrans;

			AddTimeSlot( Time(0), ct );
			TqInt i;
			for(i=1; i<cTimes(); i++)
			{
				CqMatrix matOffset = mat0 * matObjectToWorld(Time(i)).Inverse();
				ct.m_matTransform = matOffset * matTrans;
				bool flip2 = ( matOffset.Determinant() < 0 );
				ct.m_Handedness = (flip2)? !hand0 : hand0;
				AddTimeSlot( Time(i), ct);
			}
		}
		else
		{
			m_StaticMatrix = matTrans;
			m_Handedness = (flip)? !camhand : camhand;
		}
	}
}
Example #4
0
		/** \brief Create a view from imageNum of the provided file.
		 *
		 * \param file - file from which to read the image data.
		 * \param imageNum - subimage number for this view in the input file
		 * \param currToWorld - current -> world transformation matrix.
		 */
		CqShadowView(const boost::shared_ptr<IqTiledTexInputFile>& file, TqInt imageNum,
				const CqMatrix& currToWorld)
			: m_currToLight(),
			m_currToRaster(),
			m_currToRasterVec(),
			m_viewDirec(),
			m_pixels(file, imageNum)
		{
			// TODO refactor with CqShadowSampler, also refactor this function,
			// since it's a bit unweildly...
			if(!file)
				AQSIS_THROW_XQERROR(XqInternal, EqE_NoFile,
						"Cannot construct shadow map from NULL file handle");

			const CqTexFileHeader& header = file->header(imageNum);
			if(header.channelList().sharedChannelType() != Channel_Float32)
				AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
						"Shadow maps must hold 32-bit floating point data");

			// Get matrix which transforms the sample points to the light
			// camera coordinates.
			const CqMatrix* worldToLight
				= header.findPtr<Attr::WorldToCameraMatrix>();
			if(!worldToLight)
			{
				AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
						"No world -> camera matrix found in file \""
						<< file->fileName() << "\"");
			}
			m_currToLight = (*worldToLight) * currToWorld;

			// Get matrix which transforms the sample points to texture coordinates.
			const CqMatrix* worldToLightScreen
				= header.findPtr<Attr::WorldToScreenMatrix>();
			if(!worldToLightScreen)
			{
				AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
						"No world -> screen matrix found in file \""
						<< file->fileName() << "\"");
			}
			m_currToRaster = (*worldToLightScreen) * currToWorld;
			// worldToLightScreen transforms world coordinates to "screen" coordinates,
			// ie, onto the 2D box [-1,1]x[-1,1].  We instead want texture coordinates,
			// which correspond to the box [0,width]x[0,height].  In
			// addition, the direction of increase of the y-axis should be
			// swapped, since texture coordinates define the origin to be in
			// the top left of the texture rather than the bottom right.
			m_currToRaster.Translate(CqVector3D(1,-1,0));
			m_currToRaster.Scale(0.5f, -0.5f, 1);

			// Transform the light origin to "current" space to use
			// when checking the visibility of a point.
			m_lightPos = m_currToLight.Inverse()*CqVector3D(0,0,0);
			// Transform the normal (0,0,1) in light space into a normal in
			// "current" space.  The appropriate matrix is the inverse of the
			// cam -> light normal transformation, which itself is the inverse
			// transpose of currToLightVec.
			CqMatrix currToLightVec = m_currToLight;
			currToLightVec[3][0] = 0;
			currToLightVec[3][1] = 0;
			currToLightVec[3][2] = 0;
			m_viewDirec = currToLightVec.Transpose()*CqVector3D(0,0,1);
			m_viewDirec.Unit();
		}
void CqZInputFile::readHeader(std::istream& inStream, CqTexFileHeader& header)
{
	const char zFileMagicNum[] = "Aqsis ZFile";
	const TqInt magicNumSize = sizeof(zFileMagicNum)-1;
	const TqInt versionNumSize = sizeof(AQSIS_VERSION_STR)-1;
	std::vector<char> buf(max(magicNumSize, versionNumSize));

	// Read in magic number
	inStream.read(&buf[0], magicNumSize);
	if(!std::equal(buf.begin(), buf.begin() + magicNumSize, zFileMagicNum)
		|| inStream.gcount() != magicNumSize)
	{
		AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
				"Magic number missmatch in zfile");
	}

	// Read in Aqsis version.  We require this to match the current aqsis version.
	inStream.read(&buf[0], versionNumSize);
	if(!std::equal(buf.begin(), buf.begin() + versionNumSize, AQSIS_VERSION_STR)
		|| inStream.gcount() != versionNumSize)
	{
		AQSIS_THROW_XQERROR(XqBadTexture, EqE_Version,
				"zfile was created with a different aqsis version");
	}

	// Read in map width
	TqUint width = 0;
	inStream.read(reinterpret_cast<char*>(&width), sizeof(width));
	if(inStream.gcount() != sizeof(width))
		AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
			"cannot read width from aqsis z-file");
	// Read in map height
	TqUint height = 0;
	inStream.read(reinterpret_cast<char*>(&height), sizeof(height));
	if(inStream.gcount() != sizeof(height))
		AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
			"cannot read height from aqsis z-file");

	// Read world to camera transformation matrix
	CqMatrix worldToCamera;
	worldToCamera.SetfIdentity(false);
	inStream.read(reinterpret_cast<char*>(worldToCamera.pElements()), 16*sizeof(TqFloat));
	if(inStream.gcount() != 16*sizeof(TqFloat))
		AQSIS_THROW_XQERROR(XqBadTexture,EqE_BadFile,
			"could not read world to camera matrix from aqsis z-file");

	// Read world to screen transformation matrix
	CqMatrix worldToScreen;
	worldToScreen.SetfIdentity(false);
	inStream.read(reinterpret_cast<char*>(worldToScreen.pElements()), 16*sizeof(TqFloat));
	if(inStream.gcount() != 16*sizeof(TqFloat))
		AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
			"could not read world to screen matrix from aqsis z-file");

	// Save the read header attributes into the file header.
	header.setWidth(width);
	header.setHeight(height);
	header.set<Attr::WorldToScreenMatrix>(worldToScreen);
	header.set<Attr::WorldToCameraMatrix>(worldToCamera);
	// Complete the header with some other attributes implied by the file format
	header.set<Attr::TextureFormat>(TextureFormat_Shadow);
	header.channelList().addChannel(SqChannelInfo("z", Channel_Float32));
}
		/** \brief Create a view from imageNum of the provided file.
		 *
		 * \param file - file from which to read the image data.
		 * \param imageNum - subimage number for this view in the input file
		 * \param currToWorld - current -> world transformation matrix.
		 */
		CqOccView(const boost::shared_ptr<IqTiledTexInputFile>& file, TqInt imageNum,
				const CqMatrix& currToWorld)
			: m_currToLight(),
			m_currToRaster(),
			m_currToRasterVec(),
			m_negViewDirec(),
			m_pixels(file, imageNum)
		{
			// TODO refactor with CqShadowSampler, also refactor this function,
			// since it's a bit unweildly...
			if(!file)
				AQSIS_THROW_XQERROR(XqInternal, EqE_NoFile,
						"Cannot construct shadow map from NULL file handle");

			const CqTexFileHeader& header = file->header(imageNum);
			if(header.channelList().sharedChannelType() != Channel_Float32)
				AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
						"Shadow maps must hold 32-bit floating point data");

			// Get matrix which transforms the sample points to the light
			// camera coordinates.
			const CqMatrix* worldToLight
				= header.findPtr<Attr::WorldToCameraMatrix>();
			if(!worldToLight)
			{
				AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
						"No world -> camera matrix found in file \""
						<< file->fileName() << "\"");
			}
			m_currToLight = (*worldToLight) * currToWorld;

			// Get matrix which transforms the sample points to texture coordinates.
			const CqMatrix* worldToLightScreen
				= header.findPtr<Attr::WorldToScreenMatrix>();
			if(!worldToLightScreen)
			{
				AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
						"No world -> screen matrix found in file \""
						<< file->fileName() << "\"");
			}
			m_currToRaster = (*worldToLightScreen) * currToWorld;
			// worldToLightScreen transforms world coordinates to "screen" coordinates,
			// ie, onto the 2D box [-1,1]x[-1,1].  We instead want texture coordinates,
			// which correspond to the box [0,width]x[0,height].  In
			// addition, the direction of increase of the y-axis should be
			// swapped, since texture coordinates define the origin to be in
			// the top left of the texture rather than the bottom right.
			m_currToRaster.Translate(CqVector3D(1,-1,0));
			m_currToRaster.Scale(0.5f*header.width(), -0.5f*header.height(), 1);
			// This extra translation is by half a pixel width - it moves the
			// raster coordinates 
			m_currToRaster.Translate(CqVector3D(-0.5,-0.5,0));

			// Convert current -> texture transformation into a vector
			// transform rather than a point transform.
			// TODO: Put this stuff into the CqMatrix class?
			m_currToRasterVec = m_currToRaster;
			m_currToRasterVec[3][0] = 0;
			m_currToRasterVec[3][1] = 0;
			m_currToRasterVec[3][2] = 0;
			// This only really makes sense when the matrix is affine rather
			// than projective, ie, the last column is (0,0,0,h) 
			//
			// TODO: Investigate whether this is really correct.
//			assert(m_currToRasterVec[0][3] == 0);
//			assert(m_currToRasterVec[1][3] == 0);
//			assert(m_currToRasterVec[2][3] == 0);
			m_currToRasterVec[0][3] = 0;
			m_currToRasterVec[1][3] = 0;
			m_currToRasterVec[2][3] = 0;

			// Transform the normal (0,0,1) in light space into a normal in
			// "current" space.  The appropriate matrix is the inverse of the
			// cam -> light normal transformation, which itself is the inverse
			// transpose of currToLightVec.
			CqMatrix currToLightVec = m_currToLight;
			currToLightVec[3][0] = 0;
			currToLightVec[3][1] = 0;
			currToLightVec[3][2] = 0;
			m_negViewDirec = currToLightVec.Transpose()*CqVector3D(0,0,-1);
			m_negViewDirec.Unit();
		}