void SphericalXZ::ToCartesian( Matrix4* out )
{
    Matrix4 roty;	// theta
    Matrix4 rotz;	// rho
    Matrix4 trans;

    roty.SetYRotation( theta );
    rotz.SetZRotation( rho );
    trans.SetTranslation( r, 0.f, 0.f );

    *out = roty * rotz * trans;
}
Exemple #2
0
void DecalMesh::SetPosV( const Vector3F& newPos, const Matrix4& _newRot )
{
	float zRot = _newRot.CalcRotationAroundAxis(2);
	zRot = NormalizeAngleDegrees( zRot );
	
	Matrix4 newRot;
	newRot.SetZRotation( zRot );

	// We don't need to ask the container (the TerrainMesh) where we
	// will be, since the decal is patched to the terrain.
	if ( newPos.x != pos.x || newPos.y != pos.y || newRot != rotation || !InList() )
	{
		pos = newPos;
		rotation = newRot;

		Rectangle3F base;
		base.Set( -size / 2.0f, -size / 2.0f, (TERRAIN_MIN+0.01f),
				  size / 2.0f,  size / 2.0f,  (TERRAIN_MAX-0.01f) );

		if ( InList() )
			ListRemove();

		ComputeTransform();
		CalcAABB( base );
		Lilith3D::Instance()->GetQuadTree()->AddMesh( this );

		// Compute the texture matrix for this decal.
		Matrix4 center, inverse, scale;

		Transform().Invert( &inverse );				// position the texture with the mesh
		center.SetTranslation( 0.5f, 0.5f, 0.5f );	// center the decal
		scale.SetScale( 1.0f / size );		

		texMat = center * scale * inverse;
	}
}
void Screenport::SetPerspective( const grinliz::Rectangle2I* clip )
{
	uiMode = false;

	if ( clip && clip->Area() > 1 ) {
		clipInUI3D = Rectangle2F( (float)clip->min.x, (float)clip->min.y, (float)clip->max.x, (float)clip->max.y );
	}
	else {
		clipInUI3D = Rectangle2F( 0, 0, UIWidth(), UIHeight() );
	}
	GLASSERT( clipInUI3D.IsValid() );
	GLASSERT( clipInUI3D.min.x >= 0 && clipInUI3D.max.x <= UIWidth() );
	GLASSERT( clipInUI3D.min.y >= 0 && clipInUI3D.max.y <= UIHeight() );
	
	Rectangle2F scissor;
	UIToWindow( clipInUI3D,  &scissor );

	Rectangle2I clean;
	CleanScissor( scissor, &clean );
	GPUShader::SetScissor(  clean.min.x, clean.min.y, clean.Width(), clean.Height() );

	GLASSERT( uiMode == false );
	GLASSERT( EL_NEAR > 0.0f );
	GLASSERT( EL_FAR > EL_NEAR );

	frustum.zNear = EL_NEAR;
	frustum.zFar  = EL_FAR;

	// Convert from the FOV to the half angle.
	float theta = ToRadian( EL_FOV * 0.5f );
	float tanTheta = tanf( theta );
	float halfLongSide = tanTheta * frustum.zNear;

	// left, right, top, & bottom are on the near clipping
	// plane. (Not an obvious point to my mind.)

	// Also, the 3D camera applies the rotation.
	
	if ( Rotation() & 1 ) {
		float ratio = (float)clipInUI3D.Height() / (float)clipInUI3D.Width();
		
		// frustum is in original screen coordinates.
		frustum.top		=  halfLongSide;
		frustum.bottom	= -halfLongSide;
		
		frustum.left	= -ratio * halfLongSide;
		frustum.right	=  ratio * halfLongSide;
	}
	else {
		// Since FOV is specified as the 1/2 width, the ratio
		// is the height/width (different than gluPerspective)
		float ratio = (float)clipInUI3D.Height() / (float)clipInUI3D.Width();

		frustum.top		= ratio * halfLongSide;
		frustum.bottom	= -frustum.top;

		frustum.left	= -halfLongSide;
		frustum.right	=  halfLongSide;
	}
	
	Matrix4 rot;
	rot.SetZRotation( (float)(-90 * Rotation()) );
	
	// In normalized coordinates.
	projection3D.SetFrustum( frustum.left, frustum.right, frustum.bottom, frustum.top, frustum.zNear, frustum.zFar );
	projection3D = projection3D * rot;
	GPUShader::SetPerspectiveTransform( frustum.left, frustum.right,
										frustum.bottom, frustum.top,	
										frustum.zNear, frustum.zFar,
										(90*Rotation()) );
}
Exemple #4
0
void Mesh::SetPos( const grinliz::Vector3F& p, float z )
{
	Matrix4 r;
	r.SetZRotation( z );
	SetPos( p, r );
}