void HalfSpace3<Real>::Get (Vector3<Real>& rkNormal, Real& rfConstant) const
{
    rkNormal.X() = m_afTuple[0];
    rkNormal.Y() = m_afTuple[1];
    rkNormal.Z() = m_afTuple[2];
    rfConstant = m_afTuple[3];
}
void HalfSpace3<Real>::Set (const Vector3<Real>& rkNormal, Real fConstant)
{
    m_afTuple[0] = rkNormal.X();
    m_afTuple[1] = rkNormal.Y();
    m_afTuple[2] = rkNormal.Z();
    m_afTuple[3] = fConstant;
}
// http://forums.macrumors.com/showthread.php?t=547587	
void CameraRenderNode::perspective(double fovy, double zNear, double zFar) {
	Vector2 screenBounds = scene->getSettingsManager()->getPixelViewportBounds();
	
	double aspect = (double)screenBounds.X()/screenBounds.Y();
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	double xmin, xmax, ymin, ymax;
	
	ymax = zNear * tan(fovy * M_PI / 360.0);
	//ymax = zNear * tan(fovy);
	ymin = -ymax;
	xmin = ymin * aspect;
	xmax = ymax * aspect;
	
	glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glDepthMask(GL_TRUE);
	
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	
	switch(scene->getSettingsManager()->getRotation()) {
		case ROTATION_PORTRAIT:
			break;
		case ROTATION_LANDSCAPE_COUNTERCLOCKWISE:
			glRotatef(-90.0f, 0.0f, 0.0f, 1.0f);
			break;
		case ROTATION_PORTRAIT_UPSIDEDOWN:
			glRotatef(-180.0f, 0.0f, 0.0f, 1.0f);
			break;
		case ROTATION_LANDSCAPE_CLOCKWISE:
			glRotatef(-270.0f, 0.0f, 0.0f, 1.0f);
			break;
	}
	
	Quaternion* orientation = owner->getTransform()->getOrientation();
	GLfloat angle;
	Vector3 axis;	
	orientation->ToAxisAngle(axis, angle);
	angle = angle/Wm5::Mathf::PI * 180.0f;
	glRotatef(angle, axis.X(), axis.Y(), axis.Z());	
	
	Vector3* pos = owner->getTransform()->getPosition();
	glTranslatef(-pos->X(), -pos->Y(), -pos->Z());
}
void ModelLoader::ReadVertexData(FILE* apFile)
{
    Vector3 tmpVec;
    
    fscanf(apFile, "%f %f %f",&tmpVec.X(),&tmpVec.Y(),&tmpVec.Z());
    
    mVertices.push_back(tmpVec);
}
void ModelLoader::ReadNormalData(FILE* apFile)
{
    Vector3 tmpVec;
    
    fscanf(apFile, "%f %f %f",&tmpVec.X(),&tmpVec.Y(),&tmpVec.Z());
    
    mNormals.push_back(tmpVec);
}
HalfSpace3<Real>::HalfSpace3 (const Vector3<Real>& rkNormal,
    const Vector3<Real>& rkPoint)
{
    m_afTuple[0] = rkNormal.X();
    m_afTuple[1] = rkNormal.Y();
    m_afTuple[2] = rkNormal.Z();
    m_afTuple[3] = rkNormal.Dot(rkPoint);
}
Beispiel #7
0
	void Shader::SetVector3(std::string name, Vector3 value)
	{
		int uloc = SIG_FindUniform(name);
		if (uloc != -1) {
			glUniform3fARB(uloc, value.X(), value.Y(), value.Z());
		} else {
			SIG_LOG("Could not find uniform \"" << name << "\"");
		}
	}
Beispiel #8
0
void RenderUtils::drawLine(const Vector3& from, const Vector3& to, const Vector3& color) {
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glEnableClientState(GL_VERTEX_ARRAY);
	glDisable(GL_TEXTURE_2D);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);
	
	GLfloat points[6];
	points[0] = from.X();
	points[1] = from.Y();
	points[2] = from.Z();
	points[3] = to.X();
	points[4] = to.Y();
	points[5] = to.Z();
	
	glColor4f (color.X(), color.Y(), color.Z(), 1.0f);
	glVertexPointer(3, GL_FLOAT, 0, points);
	glDrawArrays(GL_LINES, 0, 2);
}
Beispiel #9
0
Plane::Plane(const Vector3 &n, double d)
{
	Vector3 norm = n;
	norm.normalize();

	a = norm.X();
	b = norm.Y();
	c = norm.Z();
	this->d = d;
}
Beispiel #10
0
Vector3 Matrix4::operator*(const Vector3 &aRHS) const
{
	if(mIdentity)
	{
		return aRHS;
	}
	else
	{
		Vector3 r;

		float fInvW = 1.0f / ( mComponents[3][0] * aRHS.X() + mComponents[3][1] * aRHS.Y() + mComponents[3][2] * aRHS.Z() + mComponents[3][3] );
		
		r.X() = ( mComponents[0][0] * aRHS.X() + mComponents[0][1] * aRHS.Y() + mComponents[0][2] * aRHS.Z() + mComponents[0][3] ) * fInvW;
		r.Y() = ( mComponents[1][0] * aRHS.X() + mComponents[1][1] * aRHS.Y() + mComponents[1][2] * aRHS.Z() + mComponents[1][3] ) * fInvW;
		r.Z() = ( mComponents[2][0] * aRHS.X() + mComponents[2][1] * aRHS.Y() + mComponents[2][2] * aRHS.Z() + mComponents[2][3] ) * fInvW;
		
		return r;
	}
}
Beispiel #11
0
void RenderUtils::drawPolygon(const std::vector<Vector3>& points, const Vector3& color, bool filled) {
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glEnableClientState(GL_VERTEX_ARRAY);
	glDisable(GL_TEXTURE_2D);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);
	
	GLfloat vertices[3 * points.size()];
	int count=0;
	for (int i = 0; i < points.size(); i++)
	{
		Vector3 p = points[i];
		vertices[count++] = p.X();
		vertices[count++] = p.Y();
		vertices[count++] = p.Z();
	}
	glColor4f (color.X(), color.Y(), color.Z(), 1.0f);
	glVertexPointer (3, GL_FLOAT, 0, vertices); 
	glDrawArrays ((filled) ? GL_TRIANGLE_FAN : GL_LINE_LOOP, 0, points.size());
}
Beispiel #12
0
Vector3<Real> Torus3<Real>::Normal (Real fS, Real fT)
{
    Real fTwoPiS = Math<Real>::TWO_PI*fS;
    Real fCosTwoPiS = Math<Real>::Cos(fTwoPiS);
    Real fSinTwoPiS = Math<Real>::Sin(fTwoPiS);
    Vector3<Real> kPos = Position(fS,fT);
    Vector3<Real> kNor(kPos.X()-m_fRo*fCosTwoPiS,kPos.Y()-m_fRo*fSinTwoPiS,
        kPos.Z());
    kNor.Normalize();
    return kNor;
}
Beispiel #13
0
HalfSpace3<Real>::HalfSpace3 (const Vector3<Real>& rkPoint0,
    const Vector3<Real>& rkPoint1, const Vector3<Real>& rkPoint2)
{
    Vector3<Real> kEdge1 = rkPoint1 - rkPoint0;
    Vector3<Real> kEdge2 = rkPoint2 - rkPoint0;
    Vector3<Real> kNormal = kEdge1.UnitCross(kEdge2);
    m_afTuple[0] = kNormal.X();
    m_afTuple[1] = kNormal.Y();
    m_afTuple[2] = kNormal.Z();
    m_afTuple[3] = kNormal.Dot(rkPoint0);
}
Beispiel #14
0
bool BoundingBox::GetCollisionNormalAndDepth(BoundingBox const& other, Vector3& normal, float& depth) const {

	Vector3 mina = Vector3(minX_, minY_, minZ_);
	Vector3 maxa = Vector3(maxX_, maxY_, maxZ_);

	Vector3 minb = Vector3(other.minX_, other.minY_, other.minZ_);
	Vector3 maxb = Vector3(other.maxX_, other.maxY_, other.maxZ_);

	// the normal of each face.
	static const Vector3 faces[6] = {
			Vector3(-1, 0, 0),
			Vector3(1, 0, 0),
			Vector3(0, -1, 0),
			Vector3(0, 1, 0),
			Vector3(0, 0, -1),
			Vector3(0, 0, 1) };

	float distances[6] = {
			(maxb.X() - mina.X()),
			(maxa.X() - minb.X()),
			(maxb.Y() - mina.Y()),
			(maxa.Y() - minb.Y()),
			(maxb.Z() - mina.Z()),
			(maxa.Z() - minb.Z())
	};

	for (unsigned int i = 0; i < 6; i++) {

		if (distances[i] <= 0.0f) {
			return false;
		}

		if ((i == 0) || (distances[i] < depth)) {
			normal = faces[i];
			depth = distances[i];
		}
	}

	return true;
}
Beispiel #15
0
Matrix4 Matrix4::GenerateOrthogonalBaseFromAxis(const Vector3 &aAxis)
{
	Vector3 FirstVector = aAxis.NormalisedCopy();
	Vector3 SecondVector;
	Vector3 ThirdVector;
	if(aAxis != Vector3::UnitX)
	{
		SecondVector = Vector3::UnitX;
	}
	else
	{
		SecondVector = Vector3::UnitY;
	}

	ThirdVector = FirstVector.CrossProduct(SecondVector).NormalisedCopy();
	SecondVector = FirstVector.CrossProduct(ThirdVector).NormalisedCopy();

	return Matrix4(		SecondVector.X(),	SecondVector.Y(),	SecondVector.Z(),	0,
						FirstVector.X(),	FirstVector.Y(),	FirstVector.Z(),	0,
						ThirdVector.X(),	ThirdVector.Y(),	ThirdVector.Z(),	0,
						0,					0,					0,					1);
}
ContEllipsoid3MinCR<Real>::ContEllipsoid3MinCR (int numPoints,
    const Vector3<Real>* points, const Vector3<Real>& C,
    const Matrix3<Real>& R, Real D[3])
{
    // Compute the constraint coefficients, of the form (A[0],A[1]) for
    // each i.
    std::vector<Vector3<Real> > A(numPoints);
    for (int i = 0; i < numPoints; ++i)
    {
        Vector3<Real> diff = points[i] - C;  // P[i] - C
        Vector3<Real> prod = diff*R;  // R^T*(P[i] - C) = (u,v,w)

        A[i].X() = prod.X()*prod.X();  // u^2
        A[i].Y() = prod.Y()*prod.Y();  // v^2
        A[i].Z() = prod.Z()*prod.Z();  // w^2
    }

    // TODO:  Sort the constraints to eliminate redundant ones.  It is clear
    // how to do this in ContEllipse2MinCR.  How to do this in 3D?

    MaxProduct(A, D);
}
Beispiel #17
0
//---------------------------------
//
//---------------------------------
void Matrix4::LookAt(const Vector3& pos, const Vector3& look, const Vector3& up)
{
    Vector3 zVector = pos - look;
    
    zVector.Normalized();

    Vector3 xVector = zVector.Cross( up		);
    Vector3 yVector = xVector.Cross( zVector );

    xVector.Normalized();
    yVector.Normalized();

    float values[ MATRIX_SIZE ] = { 
                                    xVector.X(), yVector.X(), zVector.X(), 0,
                                    xVector.Y(), yVector.Y(), zVector.Y(), 0,
                                    xVector.Z(), yVector.Z(), zVector.Z(), 0,
                                              0,           0,           0, 1
                                   };
    Matrix4 lookMatrix( values );

    lookMatrix.Translate( Vector3( -pos.X(), -pos.Y(), -pos.Z() ) );
}
Beispiel #18
0
void MeshRenderNode::render() {
    glPushMatrix();

    Vector3* position = getOwner()->getTransform()->getPosition();
    glTranslatef(position->X(), position->Y(), position->Z());

    Quaternion* orientation = getOwner()->getTransform()->getOrientation();
    GLfloat angle;
    Vector3 axis;
    orientation->ToAxisAngle(axis, angle);
    angle = angle/Wm5::Mathf::PI * 180.0f;
    glRotatef(angle, axis.X(), axis.Y(), axis.Z());

    Vector3* scale = getOwner()->getTransform()->getScale();
    glScalef(scale->X(), scale->Y(), scale->Z());

    // TODO should be using animation component
    int animationFrame = 0;
    mesh->setAnimationFrame(animationFrame);
    mesh->Render();

    glPopMatrix();
}
Beispiel #19
0
/**
 ****************************************************************************************************
	\fn			void MatrixRotationZ( Matrix &o_matrix, const Vector3 &i_position )
	\brief		Matrix rotation around Z axis creator
	\param		o_matrix output matrix
	\param		i_rotation rotation angle
	\return		NONE
 ****************************************************************************************************
*/
void GameEngine::Math::Matrix::MatrixTranslation( Matrix &o_matrix, const Vector3 &i_position )
{
	FUNCTION_START;

	assert( o_matrix._u32Column == 4 );
	assert( o_matrix._u32Row == 4 );

	o_matrix = o_matrix.Identity();
	o_matrix( 3, 0 ) = i_position.X();
	o_matrix( 3, 1 ) = i_position.Y();
	o_matrix( 3, 2 ) = i_position.Z();

	FUNCTION_FINISH;
}
Beispiel #20
0
void Wml::ContAlignedBox (int iQuantity, const Vector3<Real>* akPoint,
    Vector3<Real>& rkMin, Vector3<Real>& rkMax)
{
    rkMin = akPoint[0];
    rkMax = rkMin;

    for (int i = 1; i < iQuantity; i++)
    {
        if ( akPoint[i].X() < rkMin.X() )
            rkMin.X() = akPoint[i].X();
        else if ( akPoint[i].X() > rkMax.X() )
            rkMax.X() = akPoint[i].X();

        if ( akPoint[i].Y() < rkMin.Y() )
            rkMin.Y() = akPoint[i].Y();
        else if ( akPoint[i].Y() > rkMax.Y() )
            rkMax.Y() = akPoint[i].Y();

        if ( akPoint[i].Z() < rkMin.Z() )
            rkMin.Z() = akPoint[i].Z();
        else if ( akPoint[i].Z() > rkMax.Z() )
            rkMax.Z() = akPoint[i].Z();
    }
}
  bool KernelCollection::isWithinConvexHull(const kernel::base& k) const
  {
    NUKLEI_TRACE_BEGIN();
#ifdef NUKLEI_USE_CGAL
    using namespace cgal_convex_hull_types;
    Vector3 loc = k.getLoc();
    if (!deco_.has_key(HULL_KEY))
      NUKLEI_THROW("Undefined convex hull. Call buildConvexHull() first.");
    return deco_.get< boost::shared_ptr<Convex_hull_3> >(HULL_KEY)->bounded_side
      (Point_3(loc.X(), loc.Y(), loc.Z())) != CGAL::ON_UNBOUNDED_SIDE;
#else
    NUKLEI_THROW("This function requires CGAL. See http://nuklei.sourceforge.net/doxygen/group__install.html");
#endif
    NUKLEI_TRACE_END();
  }
Beispiel #22
0
void rms::ComputePerpVectors( const Vector3<Real> & vIn,
							  Vector3<Real> & vOut1, Vector3<Real> & vOut2, bool bInIsNormalized )
{
	Wml::Vector3<Real> vPerp(vIn);
	if ( ! bInIsNormalized )
		vPerp.Normalize();

	if ( Wml::Math<Real>::FAbs(vPerp.X()) >= Wml::Math<Real>::FAbs(vPerp.Y())
		 &&   Wml::Math<Real>::FAbs(vPerp.X()) >= Wml::Math<Real>::FAbs(vPerp.Z()) )
    {
        vOut1.X() = -vPerp.Y();
        vOut1.Y() = vPerp.X();
        vOut1.Z() = (Real)0.0;
    }
    else
    {
        vOut1.X() = (Real)0.0;
        vOut1.Y() = vPerp.Z();
        vOut1.Z() = -vPerp.Y();
    }

    vOut1.Normalize();
    vOut2 = vPerp.Cross(vOut1);	
}
Beispiel #23
0
void Camera::Sync3DAudio(Vector3 lookingAt)
{
	Vector3 completeAt = Owner()->GetTransform()->Position() + lookingAt;
	mListenerProperties.LookAtVector[0] = completeAt.X();
	mListenerProperties.LookAtVector[1] = completeAt.Y();
	mListenerProperties.LookAtVector[2] = completeAt.Z();

	mListenerProperties.UpVector[0] = Owner()->GetTransform()->Up().X();
	mListenerProperties.UpVector[1] = Owner()->GetTransform()->Up().Y();
	mListenerProperties.UpVector[2] = Owner()->GetTransform()->Up().Z();

	mListenerProperties.Position[0] = Owner()->GetTransform()->Position().X();
	mListenerProperties.Position[1] = Owner()->GetTransform()->Position().X();
	mListenerProperties.Position[2] = Owner()->GetTransform()->Position().X();

	mpAudioListener->SetListenerProperties(mListenerProperties);
}
bool
c_CurveClustering::get_recovered_curves(const t_ClusterSet &_cluster_set,
                                        const t_CurveSet &_curve_set,
                                        const t_MatrixSet &_matrix_set,
                                        t_CurveSet &_recovered)
{
    size_t n_curves = _curve_set.size();
    _recovered.reserve(n_curves);

    t_ClusterSet::const_iterator cit = _cluster_set.begin();
    t_ClusterSet::const_iterator cit_end = _cluster_set.end();
    for (; cit != cit_end; ++cit)
    {
        /*!< for each cluster */
        int index = cit->m_i_center;
        const c_Curve &curve = *(_curve_set[index]);
        const t_PointSet &controls = curve.get_controls();
        size_t n_controls = controls.size();

        const std::vector<int> &indices = cit->m_i_data;
        std::vector<int>::const_iterator cit_i = indices.begin();
        std::vector<int>::const_iterator cit_i_end = indices.end();
        for (; cit_i != cit_i_end; ++cit_i)
        {
            /*!< for each element in the cluster */
            const t_Matrix &matrix = _matrix_set[*cit_i];
            t_PointSet new_controls(n_controls);

            for (size_t i = 0; i < n_controls; ++i)
            {
                Vector3<t_Real> temp = matrix *
                        Vector3<t_Real>(controls[i].X(), controls[i].Y(), 1);
                new_controls[i] = Vector2<t_Real>(temp.X(), temp.Y());
            }

            _recovered.push_back(new c_Curve(new_controls));
        }
    }

    return true;
}
Beispiel #25
0
void MinBox3<Real>::MinimalBoxForAngles (int iQuantity,
    const Vector3<Real>* akPoint, Real afAngle[3], Box3<Real>& rkBox)
{
    Real fCos0 = Math<Real>::Cos(afAngle[0]);
    Real fSin0 = Math<Real>::Sin(afAngle[0]);
    Real fCos1 = Math<Real>::Cos(afAngle[1]);
    Real fSin1 = Math<Real>::Sin(afAngle[1]);
    Vector3<Real> kAxis(fCos0*fSin1,fSin0*fSin1,fCos1);
    Matrix3<Real> kRot(kAxis,afAngle[2]);

    Vector3<Real> kMin = akPoint[0]*kRot, kMax = kMin;
    for (int i = 1; i < iQuantity; i++)
    {
        Vector3<Real> kTest = akPoint[i]*kRot;

        if ( kTest.X() < kMin.X() )
            kMin.X() = kTest.X();
        else if ( kTest.X() > kMax.X() )
            kMax.X() = kTest.X();

        if ( kTest.Y() < kMin.Y() )
            kMin.Y() = kTest.Y();
        else if ( kTest.Y() > kMax.Y() )
            kMax.Y() = kTest.Y();

        if ( kTest.Z() < kMin.Z() )
            kMin.Z() = kTest.Z();
        else if ( kTest.Z() > kMax.Z() )
            kMax.Z() = kTest.Z();
    }

    Vector3<Real> kMid = ((Real)0.5)*(kMax + kMin);
    Vector3<Real> kRng = ((Real)0.5)*(kMax - kMin);

    rkBox.Center() = kRot*kMid;
    rkBox.Axis(0) = kRot.GetColumn(0);
    rkBox.Axis(1) = kRot.GetColumn(1);
    rkBox.Axis(2) = kRot.GetColumn(2);
    rkBox.Extent(0) = kRng.X();
    rkBox.Extent(1) = kRng.Y();
    rkBox.Extent(2) = kRng.Z();
}
bool c_CurveClustering::standardize(const c_Curve *_p_original_curve,
                                    c_Curve *&_p_standard_curve)
{
    /*!< create an oriented bounding box for sample points */
    const t_PointSet samples = _p_original_curve->get_samples();
    Box2<t_Real> box = ContOrientedBox(samples.size(), samples.data());

    /*!< ensure that extends of the box are not too small */
    if (box.Extent[0] < epsilon)
    {
        box.Extent[0] = 1;
    }
    if (box.Extent[1] < epsilon)
    {
        box.Extent[1] = 1;
    }

    /*!< set the affine matrix in the transform, using the box */
    Matrix3<t_Real> affine_matrix;
    c_Curve::t_Point const &first = samples.front();
    __set_affine_matrix(box, Vector3<t_Real>(first.X(), first.Y(), 1),
                        affine_matrix);
    m_affine_matrices.push_back(affine_matrix.Inverse());

    /*!< calculate the new standard control points */
    const t_PointSet old_controls = _p_original_curve->get_controls();
    size_t n_controls = old_controls.size();
    t_PointSet new_controls(n_controls);
    for (size_t i = 0; i < n_controls; ++i)
    {
        Vector3<t_Real> temp = affine_matrix *
                Vector3<t_Real>(old_controls[i].X(), old_controls[i].Y(), 1);
        new_controls[i] = Vector2<t_Real>(temp.X(), temp.Y());
    }

    _p_standard_curve = new c_Curve(new_controls);

    return true;
}
Vector2 CameraRenderNode::convertToWorldCoords(const Vector2& screenCoords) {
	if(guiCamera) {
		return screenCoords;
	} else {
		// TODO - this is inefficient as shit, but it works
		Vector2 rotatedBounds = getCameraBounds().min;
		
		switch(scene->getSettingsManager()->getRotation()) {
			case ROTATION_PORTRAIT:
			case ROTATION_PORTRAIT_UPSIDEDOWN:
				break;
			case ROTATION_LANDSCAPE_COUNTERCLOCKWISE:
			case ROTATION_LANDSCAPE_CLOCKWISE:
				Vector2 cameraBoundsMin = getCameraBounds().min;
				rotatedBounds = Vector2(cameraBoundsMin.Y(), cameraBoundsMin.X());
				break;
		}
		
		Vector3* pos = owner->getTransform()->getPosition();
		return zoomFactor * screenCoords + rotatedBounds + Vector2(pos->X(), pos->Y());
	}
}
Beispiel #28
0
// http://iphonedevelopment.blogspot.com/2008/10/circles-and-ellipses-in-opengl-es.html
void RenderUtils::drawEllipse(int segments, float width, float height, const Vector2& center, const Vector3& color, bool filled) {
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glEnableClientState(GL_VERTEX_ARRAY);
	glDisable(GL_TEXTURE_2D);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);
	
	glPushMatrix();
	glTranslatef(center.X(), center.Y(), 0.0);
	GLfloat vertices[segments*3];
	int count=0;
	for (GLfloat i = 0; i < (2*Wm5::Mathf::PI); i+=((2*Wm5::Mathf::PI)/segments))
	{
		vertices[count++] = (Wm5::Mathf::Cos(i)*width);
		vertices[count++] = (Wm5::Mathf::Sin(i)*height);
		vertices[count++] = 0.0f;
	}
	glColor4f (color.X(), color.Y(), color.Z(), 1.0f);
	glVertexPointer (3, GL_FLOAT, 0, vertices); 
	glDrawArrays ((filled) ? GL_TRIANGLE_FAN : GL_LINE_LOOP, 0, segments);
	
	glPopMatrix();
}
Beispiel #29
0
Real MinBox3<Real>::Volume (const Real* afAngle, void* pvData)
{
    MinBox3& rkSelf = *(MinBox3*)pvData;

    Real fCos0 = Math<Real>::Cos(afAngle[0]);
    Real fSin0 = Math<Real>::Sin(afAngle[0]);
    Real fCos1 = Math<Real>::Cos(afAngle[1]);
    Real fSin1 = Math<Real>::Sin(afAngle[1]);
    Vector3<Real> kAxis(fCos0*fSin1,fSin0*fSin1,fCos1);
    Matrix3<Real> kRot(kAxis,afAngle[2]);

    Vector3<Real> kMin = rkSelf.m_akPoint[0]*kRot, kMax = kMin;
    for (int i = 1; i < rkSelf.m_iQuantity; i++)
    {
        Vector3<Real> kTest = rkSelf.m_akPoint[i]*kRot;

        if ( kTest.X() < kMin.X() )
            kMin.X() = kTest.X();
        else if ( kTest.X() > kMax.X() )
            kMax.X() = kTest.X();

        if ( kTest.Y() < kMin.Y() )
            kMin.Y() = kTest.Y();
        else if ( kTest.Y() > kMax.Y() )
            kMax.Y() = kTest.Y();

        if ( kTest.Z() < kMin.Z() )
            kMin.Z() = kTest.Z();
        else if ( kTest.Z() > kMax.Z() )
            kMax.Z() = kTest.Z();
    }

    Real fVolume = (kMax.X()-kMin.X()) * (kMax.Y()-kMin.Y()) *
        (kMax.Z()-kMin.Z());
    return fVolume;
}
bool CylinderIntersector<real>::Intersect( const Cylinder<real>* cylinder, const Ray<real>& ray, Intersection<real>& oIntersection )
{
	real nearestDistance = std::numeric_limits<real>::max();
	real distance = 0;
	bool hasIntersection = false;

	////////////////////////////////////////////
	//////////////////IFT 3355//////////////////
	////////////////////////////////////////////
	//Ici, vous calculerez l'intersection entre
	//le rayon "ray" et le cylindre "cylinder"
	//Pensez à initialiser les quatre attributs
	//de oIntersection (retourné par référence)
	//correctement si une intersection est trouvée.
	////////////////////////////////////////////
	//////////////////IFT 3355//////////////////
	////////////////////////////////////////////

    real halfHeight = cylinder->GetHeight() / 2;
    real radius = cylinder->GetRadius();

    // Intersection with extremeties.
    Vector3<real> extremeties[2] = {
        Vector3<real>(0, halfHeight, 0),
        Vector3<real>(0, -halfHeight, 0),
    };

    for (int k = 0; k < 2; ++k) {
        Vector3<real> plane = extremeties[k];
        real denom = ray.GetDirection() * plane;
	    bool intersectsPlane = fabs(denom) > EPS;

	    // Ray intersects with the extremety.
	    if (intersectsPlane) {
            // Intersection position on the infinite plane.
	        real t = ((plane - ray.GetOrigin()) * plane) / denom;
	        Vector3<real> intersectionPos = ray.GetOrigin() + t * ray.GetDirection();
	        // Ray intersects in the window.
            if ((plane - intersectionPos).Length() <= radius &&
                ray.GetDirection() * plane < 0 &&
                t > EPS && t <= nearestDistance) {
                oIntersection.SetNormal(plane);
                oIntersection.SetPosition(intersectionPos);
                oIntersection.SetTextureCoordinates(intersectionPos);
                oIntersection.IsInside(false);
                nearestDistance = t;
                hasIntersection = true;
            }
        }
    }




    // Intersection with main body
    Vector3<real> o = Vector3<real>(ray.GetOrigin().X(), 0, ray.GetOrigin().Z());
    Vector3<real> d = Vector3<real>(ray.GetDirection().X(), 0, ray.GetDirection().Z());
    real a = d*d;
    real b = 2 * d * o;
    real c = o * o - (radius*radius);

    real discr = b*b - 4*a*c;

    if (discr < -EPS) {
        return hasIntersection;           // No intersection.
    }
    else {
        real t1 = (-b - sqrt(discr)) / (2*a);
        real t2 = (-b + sqrt(discr)) / (2*a);
        real t = std::min<real>(t1, t2);
        Vector3<real> intersectionPos = ray.GetOrigin() + t * ray.GetDirection();
        if (t >= EPS && t < nearestDistance && fabs(intersectionPos.Y()) < halfHeight+EPS) {
            oIntersection.SetNormal(intersectionPos - Vector3<real>(0, intersectionPos.Y(), 0));
            oIntersection.SetPosition(intersectionPos);
            oIntersection.SetTextureCoordinates(intersectionPos);
            oIntersection.IsInside(false);
            nearestDistance = t;
            hasIntersection = true;
        }
    }

	return hasIntersection;
}