void CQTOpenGLEPuck::RenderLED() {
    /* Side surface */
    CVector2 cVertex(BODY_RADIUS, 0.0f);
    CRadians cAngle(CRadians::TWO_PI / m_unVertices);
    CVector2 cNormal(1.0f, 0.0f);
    glBegin(GL_QUAD_STRIP);
    for(GLuint i = 0; i <= m_unVertices / 8; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), 0.0f);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), LED_ELEVATION + LED_HEIGHT);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), LED_ELEVATION);
       cVertex.Rotate(cAngle);
       cNormal.Rotate(cAngle);
    }
    glEnd();
    /* Top surface  */
    cVertex.Set(BODY_RADIUS, 0.0f);
    CVector2 cVertex2(LED_UPPER_RING_INNER_RADIUS, 0.0f);
    glBegin(GL_QUAD_STRIP);
    glNormal3f(0.0f, 0.0f, 1.0f);      
    for(GLuint i = 0; i <= m_unVertices / 8; i++) {         
       glVertex3f(cVertex2.GetX(), cVertex2.GetY(), BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT);
       cVertex.Rotate(cAngle);
       cVertex2.Rotate(cAngle);
    }
    glEnd();
 }
void experienceNet::normalPDF_sse(float* result, const float* _partitions, float _mean, float _stdDev)
{
	/* 
	CODE ADAPTED FROM boost/math/normal.hpp 

	RealType exponent = x - mean;
	exponent *= -exponent;
	exponent /= 2 * sd * sd;

	result = exp(exponent);
	result /= sd * sqrt(2 * constants::pi<RealType>());

	return result;
	*/
	const __m128& partitions = *(__m128*)_partitions;
	__m128 exponent, tmp, mean, sd;

	/* CODE ADAPTED FROM http://fastcpp.blogspot.com/2011/03/changing-sign-of-float-values-using-sse.html */
	static const __m128 signmask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));

	static const __m128 twos = _mm_set_ps1(2.0f);
	static const __m128 sqrt_pi_2_s = _mm_set_ps1(sqrt(2.0 * M_PI));

	// store mean and sd:
	mean = _mm_load_ps1(&_mean);
	sd = _mm_load_ps1(&_stdDev);

	// exponent = x - mean
	exponent = _mm_sub_ps(partitions, mean);
	// exponent *= -exponent;
	tmp = _mm_xor_ps(exponent, signmask);
	exponent = _mm_mul_ps(exponent, tmp);
	// exponent /= 2 * sd * sd;
	tmp = _mm_mul_ps(sd, sd);
	tmp = _mm_mul_ps(tmp, twos);
	exponent = _mm_div_ps(exponent, tmp);
	// exponent = exp(exponent);
	exponent = _mm_exp_ps(exponent);
	// exponent /= sd * sqrt(2 * pi)
	tmp = _mm_mul_ps(sd, sqrt_pi_2_s);
	tmp = _mm_div_ps(exponent, tmp);


#ifndef NDEBUG
	const float* _result = (float*)&tmp;
	boost::math::normal_distribution<float> cNormal(_mean, _stdDev);
	assert(fastabs(_result[0] - boost::math::pdf(cNormal, _partitions[0])) < 0.001f);
	assert(fastabs(_result[1] - boost::math::pdf(cNormal, _partitions[1])) < 0.001f);
	assert(fastabs(_result[2] - boost::math::pdf(cNormal, _partitions[2])) < 0.001f);
	assert(fastabs(_result[3] - boost::math::pdf(cNormal, _partitions[3])) < 0.001f);
#endif

	// return result:
	_mm_store_ps(result, tmp);
};
 void CQTOpenGLEPuck::RenderBody() {
    /* Set material */
    SetGreenPlasticMaterial();
    CVector2 cVertex(BODY_RADIUS, 0.0f);
    CRadians cAngle(-CRadians::TWO_PI / m_unVertices);
    /* Bottom part */
    glBegin(GL_POLYGON);
    glNormal3f(0.0f, 0.0f, -1.0f);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION);
       cVertex.Rotate(cAngle);
    }
    glEnd();
    /* Side surface */
    cAngle = -cAngle;
    CVector2 cNormal(1.0f, 0.0f);
    cVertex.Set(BODY_RADIUS, 0.0f);
    glBegin(GL_QUAD_STRIP);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), 0.0f);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION + BODY_HEIGHT);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION);
       cVertex.Rotate(cAngle);
       cNormal.Rotate(cAngle);
    }
    glEnd();
    /* Top part */
    glBegin(GL_POLYGON);
    cVertex.Set(LED_UPPER_RING_INNER_RADIUS, 0.0f);
    glNormal3f(0.0f, 0.0f, 1.0f);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT);
       cVertex.Rotate(cAngle);
    }
    glEnd();
    /* Triangle to set the direction */
    SetLEDMaterial(1.0f, 1.0f, 0.0f);
    glBegin(GL_TRIANGLES);
    glVertex3f( BODY_RADIUS * 0.7,               0.0f, BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT + 0.001f);
    glVertex3f(-BODY_RADIUS * 0.7,  BODY_RADIUS * 0.3, BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT + 0.001f);
    glVertex3f(-BODY_RADIUS * 0.7, -BODY_RADIUS * 0.3, BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT + 0.001f);
    glEnd();
 }
 void CQTOpenGLEPuck::RenderWheel() {
    /* Set material */
    SetRedPlasticMaterial();
    /* Right side */
    CVector2 cVertex(WHEEL_RADIUS, 0.0f);
    CRadians cAngle(CRadians::TWO_PI / m_unVertices);
    CVector3 cNormal(-1.0f, -1.0f, 0.0f);
    cNormal.Normalize();
    glBegin(GL_POLYGON);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ());
       glVertex3f(cVertex.GetX(), -HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       cVertex.Rotate(cAngle);
       cNormal.RotateY(cAngle);
    }
    glEnd();
    /* Left side */
    cVertex.Set(WHEEL_RADIUS, 0.0f);
    cNormal.Set(-1.0f, 1.0f, 0.0f);
    cNormal.Normalize();
    cAngle = -cAngle;
    glBegin(GL_POLYGON);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ());
       glVertex3f(cVertex.GetX(), HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       cVertex.Rotate(cAngle);
       cNormal.RotateY(cAngle);
    }
    glEnd();
    /* Tire */
    cNormal.Set(1.0f, 0.0f, 0.0f);
    cVertex.Set(WHEEL_RADIUS, 0.0f);
    cAngle = -cAngle;
    glBegin(GL_QUAD_STRIP);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ());
       glVertex3f(cVertex.GetX(), -HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       glVertex3f(cVertex.GetX(),  HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       cVertex.Rotate(cAngle);
       cNormal.RotateY(cAngle);
    }
    glEnd();
 }
Exemple #5
0
 bool CCylinder::Intersects(Real& f_t_on_ray,
                            const CRay3& c_ray) {
    /*
     * This algorithm was adapted from
     * http://www.realtimerendering.com/resources/GraphicsGems/gemsiv/ray_cyl.c
     */
    /* Vector from cylinder base to ray start */
    CVector3 cCylBase2RayStart(c_ray.GetStart());
    cCylBase2RayStart -= m_cBasePos;
    /* Ray direction and length */
    CVector3 cRayDir;
    c_ray.GetDirection(cRayDir);
    Real fRayLen = c_ray.GetLength();
    /* Vector normal to cylinder axis and ray direction */
    CVector3 cNormal(cRayDir);
    cNormal.CrossProduct(m_cAxis);
    Real fNormalLen = cNormal.Length();
    /* Are cylinder axis and ray parallel? */
    if(fNormalLen > 0) {
       /* No, they aren't parallel */
       /* Make normal have length 1 */
       cNormal /= fNormalLen;
       /* Calculate shortest distance between axis and ray
        * by projecting cCylBase2RayStart onto cNormal */
       Real fDist = Abs(cCylBase2RayStart.DotProduct(cNormal));
       /* Is fDist smaller than the cylinder radius? */
       if(fDist > m_fRadius) {
          /* No, it's not, so there can't be any intersection */
          return false;
       }
       /* If we get here, it's because the ray intersects the infinite cylinder */
       /* Create a buffer for the 4 potential intersection points
          (two on the sides, two on the bases) */
       Real fPotentialT[4];
       /* First, calculate the intersection points with the sides */
       /* Calculate the midpoint between the two intersection points */
       CVector3 cVec(cCylBase2RayStart);
       cVec.CrossProduct(m_cAxis);
       Real fMidPointDist = -cVec.DotProduct(cNormal) / fNormalLen;
       /* Calculate the distance between the midpoint and the potential t's */
       cVec = cNormal;
       cVec.CrossProduct(m_cAxis);
       cVec.Normalize();
       Real fDeltaToMidPoint = Abs(Sqrt(Square(m_fRadius) - Square(fDist)) / cRayDir.DotProduct(cVec));
       /* Calculate the potential t's on the infinite surface */
       fPotentialT[0] = (fMidPointDist - fDeltaToMidPoint) / fRayLen;
       fPotentialT[1] = (fMidPointDist + fDeltaToMidPoint) / fRayLen;
       /* Make sure these t's correspond to points within the cylinder bases */
       CVector3 cPoint;
       c_ray.GetPoint(cPoint, fPotentialT[0]);
       if((cPoint - m_cBasePos).DotProduct(m_cAxis) < 0 ||
          (cPoint - (m_cBasePos + m_fHeight * m_cAxis)).DotProduct(m_cAxis) > 0) {
          fPotentialT[0] = -1;
       }
       c_ray.GetPoint(cPoint, fPotentialT[1]);
       if((cPoint - m_cBasePos).DotProduct(m_cAxis) < 0 ||
          (cPoint - (m_cBasePos + m_fHeight * m_cAxis)).DotProduct(m_cAxis) > 0) {
          fPotentialT[1] = -1;
       }
       /* Check whether the ray is contained within the cylinder bases */
       Real fDenominator = cRayDir.DotProduct(m_cAxis);
       /* Is ray parallel to plane? */
       if(Abs(fDenominator) > 1e-6) {
          /* No, it's not parallel */
          fDenominator *= fRayLen;
          /* Bottom base */
          fPotentialT[2] =
             (m_cBasePos - c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
          /* Top base */
          fPotentialT[3] =
             (m_cBasePos + m_fHeight * m_cAxis - c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
          /* Make sure these t's are within the cylinder surface */
          c_ray.GetPoint(cPoint, fPotentialT[2]);
          CVector3 cDiff = cPoint - m_cBasePos;
          if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
             fPotentialT[2] = -1;
          c_ray.GetPoint(cPoint, fPotentialT[3]);
          cDiff = cPoint - m_cBasePos;
          if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
             fPotentialT[3] = -1;
       }
       else {
          /* Yes, it's parallel - discard the intersections */
          fPotentialT[2] = -1.0;
          fPotentialT[3] = -1.0;
       }
       /* Go through all the potential t's and get the best */
       f_t_on_ray = 2.0;
       for(UInt32 i = 0; i < 4; ++i) {
          if(fPotentialT[i] > 0.0f) {
             f_t_on_ray = Min(f_t_on_ray, fPotentialT[i]);
          }
       }
       /* Return true only if the intersection point is within the ray limits */
       return (f_t_on_ray < 1.0f);
    }
    else {
       /* Yes, ray and axis are parallel */
       /* Projection of cCylBase2RayStart onto the axis */
       Real fProj = cCylBase2RayStart.DotProduct(m_cAxis);
       /* Radial vector */
       CVector3 cRadial(cCylBase2RayStart);
       cRadial -= fProj * m_cAxis;
       Real fDist = cRadial.Length();
       /* Is ray within the cylinder radius? */
       if(fDist > m_fRadius) {
          /* No, it's not */
          return false;
       }
       /* If we get here, it's because the ray might intersect the cylinder bases */
       Real fDenominator = cRayDir.DotProduct(m_cAxis) * fRayLen;
       /* Create a buffer for the 2 potential intersection points */
       Real fPotentialT[2];
       /* Bottom base */
       fPotentialT[0] =
          (m_cBasePos-c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
       /* Top base */
       fPotentialT[1] =
          (m_cBasePos + m_fHeight * m_cAxis - c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
       /* Make sure these t's are within the cylinder surface */
       CVector3 cPoint;
       c_ray.GetPoint(cPoint, fPotentialT[0]);
       CVector3 cDiff = cPoint - m_cBasePos;
       if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
          fPotentialT[0] = -1;
       c_ray.GetPoint(cPoint, fPotentialT[1]);
       cDiff = cPoint - m_cBasePos;
       if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
          fPotentialT[1] = -1;
       /* Go through all the potential t's and get the best */
       f_t_on_ray = 2.0;
       for(UInt32 i = 0; i < 2; ++i) {
          if(fPotentialT[i] > 0.0f) {
             f_t_on_ray = Min(f_t_on_ray, fPotentialT[i]);
          }
       }
       /* Return true only if the intersection point is within the ray limits */
       return (f_t_on_ray < 1.0f);
    }
 }