Example #1
0
Vector3<Real> Curve3<Real>::GetNormal (Real t) const
{
	Vector3<Real> velocity = GetFirstDerivative(t);
	Vector3<Real> acceleration = GetSecondDerivative(t);
	Real VDotV = velocity.Dot(velocity);
	Real VDotA = velocity.Dot(acceleration);
	Vector3<Real> normal = VDotV*acceleration - VDotA*velocity;
	normal.Normalize();
	return normal;
}
Example #2
0
//----------------------------------------------------------------------------
Vector3 Curve3::GetNormal (Real fTime) const
{
    Vector3 kVelocity = GetFirstDerivative(fTime);
    Vector3 kAcceleration = GetSecondDerivative(fTime);
    Real fVDotV = kVelocity.Dot(kVelocity);
    Real fVDotA = kVelocity.Dot(kAcceleration);
    Vector3 kNormal = fVDotV*kAcceleration - fVDotA*kVelocity;
    kNormal.Unitize();
    return kNormal;
}
Example #3
0
//----------------------------------------------------------------------------
// @ ::DistanceSquared()
// ---------------------------------------------------------------------------
// Returns the distance squared between line and point.
//-----------------------------------------------------------------------------
float DistanceSquared( const Line3& line, const Vector3& point, float& t_c )
{
    Vector3 w = point - line.mOrigin;
    float vsq = line.mDirection.Dot(line.mDirection);
    float proj = w.Dot(line.mDirection);
    t_c = proj/vsq; 

    return w.Dot(w) - t_c*proj;

}   // End of ::DistanceSquared()
Example #4
0
	bool LinePlaneIntersection(Vector3 linePoint, Vector3 lineDir, Vector3 planePoint, Vector3 planeNormal, float & t)
	{
		float nDotDir = planeNormal.Dot(lineDir);
		if (nDotDir != 0.f) {
			t = (planeNormal.Dot(planePoint) - planeNormal.Dot(linePoint)) / nDotDir;
			return true;
		}
		// parallel
		return false;
	}
Example #5
0
	void ClosestPoints(Vector3 p, Vector3 pDir, Vector3 q, Vector3 qDir, float & pt, float & qt)
	{
		Vector3 w = p - q;
		float a = p.LengthSquared();
		float b = pDir.Dot(qDir);
		float c = q.LengthSquared();
		float d = pDir.Dot(w);
		float e = qDir.Dot(w);
		pt = (b * e - c * d) / (a * c - b * b);
		qt = (a * e - b * d) / (a * c - b * b);
	}
Example #6
0
/******************************************************************************
vector projection
dir vector must be normalized for maximum accuracy
******************************************************************************/
Vector3 Line::vectorProjection(Vector3& projected, Vector3& dir)
{
	Vector3 part1;
	part1.x = projected.Dot(dir);
	part1.y = dir.Dot(dir);

	Vector3 returnVec;
	returnVec.x = (part1.x * dir.x) / part1.y;
	returnVec.y = (part1.x * dir.y) / part1.y;

	return returnVec;
}
Example #7
0
void Wml::BoxProjection (const Vector3<Real>& rkAxis,
    const Box3<Real>& rkBox, Real& rfMin, Real& rfMax)
{
    Real fOrigin = rkAxis.Dot(rkBox.Center());
    Real fMaximumExtent =
        Math<Real>::FAbs(rkBox.Extent(0)*rkAxis.Dot(rkBox.Axis(0))) +
        Math<Real>::FAbs(rkBox.Extent(1)*rkAxis.Dot(rkBox.Axis(1))) +
        Math<Real>::FAbs(rkBox.Extent(2)*rkAxis.Dot(rkBox.Axis(2)));

    rfMin = fOrigin - fMaximumExtent;
    rfMax = fOrigin + fMaximumExtent;
}
Example #8
0
Box3<Real> Wml::ContOrientedBox (int iQuantity, const Vector3<Real>* akPoint)
{
    Box3<Real> kBox;

    GaussPointsFit(iQuantity,akPoint,kBox.Center(),kBox.Axes(),
        kBox.Extents());

    // Let C be the box center and let U0, U1, and U2 be the box axes.  Each
    // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2.  The
    // following code computes min(y0), max(y0), min(y1), max(y1), min(y2),
    // and max(y2).  The box center is then adjusted to be
    //   C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 +
    //        0.5*(min(y2)+max(y2))*U2

    Vector3<Real> kDiff = akPoint[0] - kBox.Center();
    Real fY0Min = kDiff.Dot(kBox.Axis(0)), fY0Max = fY0Min;
    Real fY1Min = kDiff.Dot(kBox.Axis(1)), fY1Max = fY1Min;
    Real fY2Min = kDiff.Dot(kBox.Axis(2)), fY2Max = fY2Min;

    for (int i = 1; i < iQuantity; i++)
    {
        kDiff = akPoint[i] - kBox.Center();

        Real fY0 = kDiff.Dot(kBox.Axis(0));
        if ( fY0 < fY0Min )
            fY0Min = fY0;
        else if ( fY0 > fY0Max )
            fY0Max = fY0;

        Real fY1 = kDiff.Dot(kBox.Axis(1));
        if ( fY1 < fY1Min )
            fY1Min = fY1;
        else if ( fY1 > fY1Max )
            fY1Max = fY1;

        Real fY2 = kDiff.Dot(kBox.Axis(2));
        if ( fY2 < fY2Min )
            fY2Min = fY2;
        else if ( fY2 > fY2Max )
            fY2Max = fY2;
    }

    kBox.Center() += (((Real)0.5)*(fY0Min+fY0Max))*kBox.Axis(0) +
        (((Real)0.5)*(fY1Min+fY1Max))*kBox.Axis(1) +
        (((Real)0.5)*(fY2Min+fY2Max))*kBox.Axis(2);

    kBox.Extent(0) = ((Real)0.5)*(fY0Max - fY0Min);
    kBox.Extent(1) = ((Real)0.5)*(fY1Max - fY1Min);
    kBox.Extent(2) = ((Real)0.5)*(fY2Max - fY2Min);

    return kBox;
}
Example #9
0
void ParticleSystem::checkWallCollisions(){
    float wallStiffness = 500.0;
    float wallDamper = 0.5;
    float radius = h*0.2;
    float diff;
    float adj;
    Vector3 normal;
    float padding = h * 0.7;
    
    for(int i = 0; i < NumParticles; i++){
        Particle * p = Particles[i];
        
        //X Walls - Left and Right
        normal = Vector3(1,0,0);
        diff = 2*radius - (p->getPosition().x - (bMin.x+padding));
        if(diff > EPSILON){
            adj = wallStiffness * diff - wallDamper*(normal.Dot(p->getPrevVelocity()));
            p->setAcceleration(p->getAcceleration() + float(adj)*normal);
        }
        
        normal = Vector3(-1,0,0);
        diff = 2*radius - ((bMax.x-padding) - p->getPosition().x);
        if(diff > EPSILON){
            adj = wallStiffness * diff - wallDamper*(normal.Dot(p->getPrevVelocity()));
            p->setAcceleration(p->getAcceleration() + float(adj)*normal);
        }
        
        //Y wall bottom
        normal = Vector3(0,1,0);
        diff = 2*radius - (p->getPosition().y - (bMin.y+padding));
        if(diff > EPSILON){
            printf("HIT\n");
            adj = wallStiffness * diff - wallDamper*(normal.Dot(p->getPrevVelocity()));
            p->setAcceleration(p->getAcceleration() + (float(adj)*normal));
        }
        
        //Z walls - Front and Back
        normal = Vector3(0,0,1);
        diff = 2*radius - (p->getPosition().z - (bMin.z+padding));
        if(diff > EPSILON){
            adj = wallStiffness * diff - wallDamper*(normal.Dot(p->getPrevVelocity()));
            p->setAcceleration(p->getAcceleration() + float(adj)*normal);
        }
        
        normal = Vector3(0,0,-1);
        diff = 2*radius - ((bMax.z-padding) - p->getPosition().z);
        if(diff > EPSILON){
            adj = wallStiffness * diff - wallDamper*(normal.Dot(p->getPrevVelocity()));
            p->setAcceleration(p->getAcceleration() + float(adj)*normal);
        }
    }
}
Example #10
0
//----------------------------------------------------------------------------
// @ BoundingSphere::Intersect()
// ---------------------------------------------------------------------------
// Determine intersection between sphere and line
//-----------------------------------------------------------------------------
bool
BoundingSphere::Intersect( const Line3& line ) const
{
    // compute intermediate values
    Vector3 w = mCenter - line.GetOrigin();
    float wsq = w.Dot(w);
    float proj = w.Dot(line.GetDirection());
    float rsq = mRadius*mRadius;
    float vsq = line.GetDirection().Dot(line.GetDirection());

    // test length of difference vs. radius
    return ( vsq*wsq - proj*proj <= vsq*rsq );
}
Example #11
0
    bool IntrLine3Box3<Real>::DoClipping ( Real t0, Real t1,
                                           const Vector3<Real>& origin, const Vector3<Real>& direction,
                                           const Box3<Real>& box, bool solid, int& quantity, Vector3<Real> point[2],
                                           int& intrType )
    {
        // Convert linear component to box coordinates.
        Vector3<Real> diff = origin - box.Center;
        Vector3<Real> BOrigin(
            diff.Dot( box.Axis[0] ),
            diff.Dot( box.Axis[1] ),
            diff.Dot( box.Axis[2] )
        );
        Vector3<Real> BDirection(
            direction.Dot( box.Axis[0] ),
            direction.Dot( box.Axis[1] ),
            direction.Dot( box.Axis[2] )
        );

        Real saveT0 = t0, saveT1 = t1;
        bool notAllClipped =
            Clip( +BDirection.X(), -BOrigin.X() - box.Extent[0], t0, t1 ) &&
            Clip( -BDirection.X(), +BOrigin.X() - box.Extent[0], t0, t1 ) &&
            Clip( +BDirection.Y(), -BOrigin.Y() - box.Extent[1], t0, t1 ) &&
            Clip( -BDirection.Y(), +BOrigin.Y() - box.Extent[1], t0, t1 ) &&
            Clip( +BDirection.Z(), -BOrigin.Z() - box.Extent[2], t0, t1 ) &&
            Clip( -BDirection.Z(), +BOrigin.Z() - box.Extent[2], t0, t1 );

        if ( notAllClipped && ( solid || t0 != saveT0 || t1 != saveT1 ) )
        {
            if ( t1 > t0 )
            {
                intrType = IT_SEGMENT;
                quantity = 2;
                point[0] = origin + t0 * direction;
                point[1] = origin + t1 * direction;
            }
            else
            {
                intrType = IT_POINT;
                quantity = 1;
                point[0] = origin + t0 * direction;
            }
        }
        else
        {
            quantity = 0;
            intrType = IT_EMPTY;
        }

        return intrType != IT_EMPTY;
    }
Example #12
0
Real DistLine3Ray3<Real>::GetSquared ()
{
	Vector3<Real> kDiff = mLine->Origin - mRay->Origin;
	Real a01 = -mLine->Direction.Dot(mRay->Direction);
	Real b0 = kDiff.Dot(mLine->Direction);
	Real c = kDiff.SquaredLength();
	Real det = Math<Real>::FAbs((Real)1 - a01*a01);
	Real b1, s0, s1, sqrDist;

	if (det >= Math<Real>::ZERO_TOLERANCE)
	{
		b1 = -kDiff.Dot(mRay->Direction);
		s1 = a01*b0 - b1;

		if (s1 >= (Real)0)
		{
			// Two interior points are closest, one on line and one on ray.
			Real invDet = ((Real)1)/det;
			s0 = (a01*b1 - b0)*invDet;
			s1 *= invDet;
			sqrDist = s0*(s0 + a01*s1 + ((Real)2)*b0) +
			          s1*(a01*s0 + s1 + ((Real)2)*b1) + c;
		}
		else
		{
			// Origin of ray and interior point of line are closest.
			s0 = -b0;
			s1 = (Real)0;
			sqrDist = b0*s0 + c;
		}
	}
	else
	{
		// Lines are parallel, closest pair with one point at ray origin.
		s0 = -b0;
		s1 = (Real)0;
		sqrDist = b0*s0 + c;
	}

	mClosestPoint0 = mLine->Origin + s0*mLine->Direction;
	mClosestPoint1 = mRay->Origin + s1*mRay->Direction;
	mLineParameter = s0;
	mRayParameter = s1;

	// Account for numerical round-off errors.
	if (sqrDist < (Real)0)
	{
		sqrDist = (Real)0;
	}
	return sqrDist;
}
Example #13
0
bool IntersectTriangle(Vector3& orig, Vector3& dir,
                       Vector3& v0, Vector3& v1, Vector3& v2)
{
    double t,  u,  v;
    // E1
    Vector3 E1 = v1 - v0;

    // E2
    Vector3 E2 = v2 - v0;

    // P
    Vector3 P = dir.Cross(E2);

    // determinant
    double det = E1.Dot(P);

    // keep det > 0, modify T accordingly
    Vector3 T;
    if( det >0 )
    {
        T = orig - v0;
    }
    else
    {
        T = v0 - orig;
        det = -det;
    }

    // If determinant is near zero, ray lies in plane of triangle
    if( det < 0.0001f )
        return false;

    // Calculate u and make sure u <= 1
    u = T.Dot(P);
    if( u < 0.0f || u > det )
        return false;

    // Q
    Vector3 Q = T.Cross(E1);

    // Calculate v and make sure u + v <= 1
    v = dir.Dot(Q);
    if( v < 0.0f || u + v > det )
        return false;

    // Calculate t, scale parameters, ray intersects triangle
    t = E2.Dot(Q);

    if (t < 0.0f) return false;
    return true;
}
Example #14
0
//----------------------------------------------------------------------------
void Curve3::GetFrame (Real fTime, Vector3& rkPosition, Vector3& rkTangent,
    Vector3& rkNormal, Vector3& rkBinormal) const
{
    rkPosition = GetPosition(fTime);
    Vector3 kVelocity = GetFirstDerivative(fTime);
    Vector3 kAcceleration = GetSecondDerivative(fTime);
    Real fVDotV = kVelocity.Dot(kVelocity);
    Real fVDotA = kVelocity.Dot(kAcceleration);
    rkNormal = fVDotV*kAcceleration - fVDotA*kVelocity;
    rkNormal.Unitize();
    rkTangent = kVelocity;
    rkTangent.Unitize();
    rkBinormal = rkTangent.Cross(rkNormal);
}
Example #15
0
CylinderFit3<Real>::CylinderFit3 (int numPoints, const Vector3<Real>* points,
    Vector3<Real>& center, Vector3<Real>& axis, Real& radius, Real& height,
    bool inputsAreInitialGuess)
{
    Real invRSqr = (Real)1;
    if (!inputsAreInitialGuess)
    {
        // Find the least-squares line that fits the data and use it as an
        // initial guess for the cylinder axis.
        Line3<Real> line = OrthogonalLineFit3(numPoints, points);
        center = line.Origin;
        axis = line.Direction;
    }

    mError = Math<Real>::MAX_REAL;
    const int iMax = 8;
    int i;
    for (i = 0; i < iMax; ++i)
    {
        mError = UpdateInvRSqr(numPoints, points, center, axis, invRSqr);
        mError = UpdateDirection(numPoints, points, center, axis, invRSqr);
        mError = UpdateCenter(numPoints, points, center, axis, invRSqr);
    }

    // Compute the radius.
    radius = Math<Real>::InvSqrt(invRSqr);

    // Project points onto fitted axis to determine extent of cylinder along
    // the axis.
    Real tMin = axis.Dot(points[0] - center);
    Real tMax = tMin;
    for (i = 1; i < numPoints; ++i)
    {
        Real t = axis.Dot(points[i] - center);
        if (t < tMin)
        {
            tMin = t;
        }
        else if (t > tMax)
        {
            tMax = t;
        }
    }

    // Compute the height.  Adjust the center to point that projects to
    // midpoint of extent.
    height = tMax - tMin;
    center += (((Real)0.5)*(tMin + tMax))*axis;
}
Example #16
0
 void Curve3<Real>::GetFrame ( Real t, Vector3<Real>& position,
                               Vector3<Real>& tangent, Vector3<Real>& normal, Vector3<Real>& binormal )
 const
 {
     position = GetPosition( t );
     Vector3<Real> velocity = GetFirstDerivative( t );
     Vector3<Real> acceleration = GetSecondDerivative( t );
     Real VDotV = velocity.Dot( velocity );
     Real VDotA = velocity.Dot( acceleration );
     normal = VDotV * acceleration - VDotA * velocity;
     normal.Normalize();
     tangent = velocity;
     tangent.Normalize();
     binormal = tangent.Cross( normal );
 }
Example #17
0
CylinderFit3<Real>::CylinderFit3 (int iQuantity, const Vector3<Real>* akPoint,
    Vector3<Real>& rkC, Vector3<Real>& rkU, Real& rfR, Real& rfH,
    bool bInputsAreInitialGuess)
{
    Real fInvRSqr = (Real)1.0;
    if (!bInputsAreInitialGuess)
    {
        // Find the least-squares line that fits the data and use it as an
        // initial guess for the cylinder axis.
        Line3<Real> kLine = OrthogonalLineFit3(iQuantity,akPoint);
        rkC = kLine.Origin;
        rkU = kLine.Direction;
    }

    m_fError = Math<Real>::MAX_REAL;
    const int iMax = 8;
    int i;
    for (i = 0; i < iMax; i++)
    {
        m_fError = UpdateInvRSqr(iQuantity,akPoint,rkC,rkU,fInvRSqr);
        m_fError = UpdateDirection(iQuantity,akPoint,rkC,rkU,fInvRSqr);
        m_fError = UpdateCenter(iQuantity,akPoint,rkC,rkU,fInvRSqr);
    }

    // Compute the radius.
    rfR = Math<Real>::InvSqrt(fInvRSqr);

    // Project points onto fitted axis to determine extent of cylinder along
    // the axis.
    Real fTMin = rkU.Dot(akPoint[0]-rkC), fTMax = fTMin;
    for (i = 1; i < iQuantity; i++)
    {
        Real fT = rkU.Dot(akPoint[i]-rkC);
        if (fT < fTMin)
        {
            fTMin = fT;
        }
        else if (fT > fTMax)
        {
            fTMax = fT;
        }
    }

    // Compute the height.  Adjust the center to point that projects to
    // midpoint of extent.
    rfH = fTMax - fTMin;
    rkC += ((Real)0.5)*(fTMin+fTMax)*rkU;
}
void    ObjectRenderer::RenderShadow(int pass, const Vector3& light, const Vector3& observer){
    if(pass<0) return;

    glPushMatrix();

    Vector3 objLight;
    Vector3 objObserver;


    Vector3 obsObj = mObject->GetReferenceFrame().GetOrigin();
    obsObj -= observer;

    Vector3 ligObj = mObject->GetReferenceFrame().GetOrigin();
    ligObj -= light;

    glMultMatrixf(mObject->GetReferenceFrame().GetHMatrix().RowOrderForceFloat());

    mObject->GetReferenceFrame().GetInverse().GetHMatrix().Transform(light,     objLight);
    mObject->GetReferenceFrame().GetInverse().GetHMatrix().Transform(observer,  objObserver);

    for(int i=0;i<int(mShapes.size());i++){
        if(mShapes[i]->shape){
            GL3DObject::RenderShadowInitPass(pass +(obsObj.Dot(ligObj)>0?0:2));
            mShapes[i]->shape->RenderShadowPass(pass, objLight);
        }
    }

    glPopMatrix();

    AbstractRenderer::RenderShadow(pass,light,observer);
}
Example #19
0
Real DistVector3Box3<Real>::GetSquared ()
{
    // work in the box's coordinate system
    Vector3<Real> kDiff = *m_pkVector - m_pkBox->Center;

    // compute squared distance and closest point on box
    Real fSqrDistance = (Real)0.0, fDelta;
    Vector3<Real> kClosest;
    int i;
    for (i = 0; i < 3; i++)
    {
        kClosest[i] = kDiff.Dot(m_pkBox->Axis[i]);
        if (kClosest[i] < -m_pkBox->Extent[i])
        {
            fDelta = kClosest[i] + m_pkBox->Extent[i];
            fSqrDistance += fDelta*fDelta;
            kClosest[i] = -m_pkBox->Extent[i];
        }
        else if (kClosest[i] > m_pkBox->Extent[i])
        {
            fDelta = kClosest[i] - m_pkBox->Extent[i];
            fSqrDistance += fDelta*fDelta;
            kClosest[i] = m_pkBox->Extent[i];
        }
    }

    m_kClosestPoint0 = *m_pkVector;
    m_kClosestPoint1 = m_pkBox->Center;
    for (i = 0; i < 3; i++)
    {
        m_kClosestPoint1 += kClosest[i]*m_pkBox->Axis[i];
    }

    return fSqrDistance;
}
    bool IntrSphere3Sphere3<Real>::Test ( Real tmax,
                                          const Vector3<Real>& velocity0, const Vector3<Real>& velocity1 )
    {
        Vector3<Real> relVelocity = velocity1 - velocity0;
        Real a = relVelocity.SquaredLength();
        Vector3<Real> CDiff = mSphere1->Center - mSphere0->Center;
        Real c = CDiff.SquaredLength();
        Real rSum = mSphere0->Radius + mSphere1->Radius;
        Real rSumSqr = rSum * rSum;

        if ( a > ( Real )0 )
        {
            Real b = CDiff.Dot( relVelocity );
            if ( b <= ( Real )0 )
            {
                if ( -tmax * a <= b )
                {
                    return a * c - b * b <= a * rSumSqr;
                }
                else
                {
                    return tmax * ( tmax * a + ( ( Real )2 ) * b ) + c <= rSumSqr;
                }
            }
        }

        return c <= rSumSqr;
    }
Example #21
0
bool Wml::Culled (const Plane3<Real>& rkPlane,
    const Ellipsoid3<Real>& rkEllipsoid, bool bUnitNormal)
{
    Vector3<Real> kNormal = rkPlane.GetNormal();
    Real fConstant = rkPlane.GetConstant();
    if ( !bUnitNormal )
    {
        Real fLength = kNormal.Normalize();
        fConstant /= fLength;
    }

    Real fDiscr = kNormal.Dot(rkEllipsoid.InverseA()*kNormal);
    Real fRoot = Math<Real>::Sqrt(Math<Real>::FAbs(fDiscr));
    Real fSDist = kNormal.Dot(rkEllipsoid.Center()) - fConstant;
    return fSDist <= -fRoot;
}
//----------------------------------------------------------------------------
bool Mgc::TestIntersection (const Plane& rkPlane,
    const Ellipsoid& rkEllipsoid, bool bUnitNormal)
{
    Vector3 kNormal = rkPlane.Normal();
    Real fConstant = rkPlane.Constant();
    if ( !bUnitNormal )
    {
        Real fLength = kNormal.Unitize();
        fConstant /= fLength;
    }

    Real fDiscr = kNormal.Dot(rkEllipsoid.InverseA()*kNormal);
    Real fRoot = Math::Sqrt(Math::FAbs(fDiscr));
    Real fSDist = kNormal.Dot(rkEllipsoid.Center()) - fConstant;
    return Math::FAbs(fSDist) <= fRoot;
}
//----------------------------------------------------------------------------
void ConvexPolyhedron::Create (const vector<Vector3>& rakPoint,
                               const vector<int>& raiConnect)
{
    assert( rakPoint.size() >= 4 && raiConnect.size() >= 4 );

    int iVQuantity = rakPoint.size();
    int iTQuantity = raiConnect.size()/3;
    int iEQuantity = iVQuantity + iTQuantity - 2;
    Reset(iVQuantity,iEQuantity,iTQuantity);
    m_akPoint = rakPoint;

    // Copy polyhedron points into vertex array.  Compute centroid for use in
    // making sure the triangles are counterclockwise oriented when viewed
    // from the outside.
    ComputeCentroid();

    // get polyhedron edge and triangle information
    for (int iT = 0, iIndex = 0; iT < iTQuantity; iT++)
    {
        // get vertex indices for triangle
        int iV0 = raiConnect[iIndex++];
        int iV1 = raiConnect[iIndex++];
        int iV2 = raiConnect[iIndex++];

        // make sure triangle is counterclockwise
        Vector3& rkV0 = m_akPoint[iV0];
        Vector3& rkV1 = m_akPoint[iV1];
        Vector3& rkV2 = m_akPoint[iV2];

        Vector3 kDiff = m_kCentroid - rkV0;
        Vector3 kE1 = rkV1 - rkV0;
        Vector3 kE2 = rkV2 - rkV0;
        Vector3 kNormal = kE1.Cross(kE2);
        Real fLength = kNormal.Length();
        if ( fLength > 1e-06f )
        {
            kNormal /= fLength;
        }
        else
        {
            kNormal = kDiff;
            kNormal.Unitize();
        }

        Real fDistance = kNormal.Dot(kDiff);

        if ( fDistance < 0.0f )
        {
            // triangle is counterclockwise
            Insert(iV0,iV1,iV2);
        }
        else
        {
            // triangle is clockwise
            Insert(iV0,iV2,iV1);
        }
    }

    UpdatePlanes();
}
Example #24
0
bool FrustumPickVisitor::AddHitTriangle(const Vector3& v0,const Vector3& v1,const Vector3& v2)
{
	float32_t dot = 0.f;
	Vector3 normal ( (v2 - v1).Cross (v1 - v0) );

	if (m_Camera->GetShadingMode() != ShadingMode::Wireframe && m_Camera->IsBackFaceCulling())
	{
		Vector3 cameraDir;
		m_Camera->GetDirection (cameraDir);
		m_CurrentInverseWorldTransform.TransformNormal (cameraDir);
		dot = normal.Dot (cameraDir);
	}

	if ( dot >= 0.f )
	{
		// allocate a hit
		PickHit* hit = AddHit();

		// our intersection point is center of the triangle (HACK)
		Vector3 intersection ( ( v0 + v1 + v2 ) / 3.f );
		// transform values into world space
		m_CurrentWorldTransform.TransformVertex(intersection);

		// set intersection in world space (we use FLT_MAX for the distance since the distance is spacial)
		if (!HasFlags(PickFlags::IgnoreIntersection))
		{
			hit->SetIntersection( intersection );
		}

		return true;
	}

	return false;
}
bool IntrSphere3Sphere3<Real>::Test (Real fTMax,
    const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
{
    Vector3<Real> kVDiff = rkVelocity1 - rkVelocity0;
    Real fA = kVDiff.SquaredLength();
    Vector3<Real> kCDiff = m_rkSphere1.Center - m_rkSphere0.Center;
    Real fC = kCDiff.SquaredLength();
    Real fRSum = m_rkSphere0.Radius + m_rkSphere1.Radius;
    Real fRSumSqr = fRSum*fRSum;

    if (fA > (Real)0.0)
    {
        Real fB = kCDiff.Dot(kVDiff);
        if (fB <= (Real)0.0)
        {
            if (-fTMax*fA <= fB)
            {
                return fA*fC - fB*fB <= fA*fRSumSqr;
            }
            else
            {
                return fTMax*(fTMax*fA + ((Real)2.0)*fB) + fC <= fRSumSqr;
            }
        }
    }

    return fC <= fRSumSqr;
}
Example #26
0
Real Mgc::SqrDistance (const Vector3& rkPoint, const Line3& rkLine,

    Real* pfParam)

{

    Vector3 kDiff = rkPoint - rkLine.Origin();

    Real fSqrLen = rkLine.Direction().SquaredLength();

    Real fT = kDiff.Dot(rkLine.Direction())/fSqrLen;

    kDiff -= fT*rkLine.Direction();



    if ( pfParam )

        *pfParam = fT;



    return kDiff.SquaredLength();

}
Example #27
0
//----------------------------------------------------------------------------
// @ ::Merge()
// ---------------------------------------------------------------------------
// Merge two spheres together to create a new one
//-----------------------------------------------------------------------------
void
Merge( BoundingSphere& result, 
       const BoundingSphere& s0, const BoundingSphere& s1 )
{
    // get differences between them
    Vector3 diff = s1.mCenter - s0.mCenter;
    float distsq = diff.Dot(diff);
    float radiusdiff = s1.mRadius - s0.mRadius;

    // if one sphere inside other
    if ( distsq <= radiusdiff*radiusdiff )
    {
        if ( s0.mRadius > s1.mRadius )
            result = s0;
        else
            result = s1;
        return;
    }

    // build new sphere
    float dist = Sqrt( distsq );
    float radius = 0.5f*( s0.mRadius + s1.mRadius + dist );
    Vector3 center = s0.mCenter;
    if (!gfx::IsZero( dist ))
        center += ((radius-s0.mRadius)/dist)*diff;

    result.SetRadius( radius );
    result.SetCenter( center );

}   // End of ::Merge()
Example #28
0
void Triangle::computeForces(Vector3 &airVelocity)
{
	this->airVelocity = airVelocity;
	Vector3 velocity = (p1->velocity + p2->velocity + p3->velocity) / 3;

	Vector3 realVelocity = velocity - airVelocity;

	if (realVelocity.Mag() > 0)
	{
		Vector3 *one = new Vector3();
		Vector3 *two = new Vector3();
		one->Cross(p2->position - p1->position, p3->position - p1->position);
		two->Cross(p2->position - p1->position, p3->position - p1->position);
		one->Normalize();
		normal = *one;

		float a0 = 0.5 * two->Mag();
		float a = a0 * (realVelocity.Dot(normal) / realVelocity.Mag());

		Vector3 fAero = -0.5 * density * realVelocity.Mag2() *a *normal;

		Vector3 fAeroParticle = fAero / 3;

		if (!p1->pinned)
			p1->applyForce(fAeroParticle);
		if (!p2->pinned)
			p2->applyForce(fAeroParticle);
		if (!p3->pinned)
			p3->applyForce(fAeroParticle);

		delete one; 
		delete two; 		
	}
}
bool IntrSegment3Triangle3<Real>::Test ()
{
    // Compute the offset origin, edges, and normal.
    Vector3<Real> diff = mSegment->Center - mTriangle->V[0];
    Vector3<Real> edge1 = mTriangle->V[1] - mTriangle->V[0];
    Vector3<Real> edge2 = mTriangle->V[2] - mTriangle->V[0];
    Vector3<Real> normal = edge1.Cross(edge2);

    // Solve Q + t*D = b1*E1 + b2*E2 (Q = diff, D = segment direction,
    // E1 = edge1, E2 = edge2, N = Cross(E1,E2)) by
    //   |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
    //   |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
    //   |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
    Real DdN = mSegment->Direction.Dot(normal);
    Real sign;
    if (DdN > Math<Real>::ZERO_TOLERANCE)
    {
        sign = (Real)1;
    }
    else if (DdN < -Math<Real>::ZERO_TOLERANCE)
    {
        sign = (Real)-1;
        DdN = -DdN;
    }
    else
    {
        // Segment and triangle are parallel, call it a "no intersection"
        // even if the segment does intersect.
        mIntersectionType = IT_EMPTY;
        return false;
    }

    Real DdQxE2 = sign*mSegment->Direction.Dot(diff.Cross(edge2));
    if (DdQxE2 >= (Real)0)
    {
        Real DdE1xQ = sign*mSegment->Direction.Dot(edge1.Cross(diff));
        if (DdE1xQ >= (Real)0)
        {
            if (DdQxE2 + DdE1xQ <= DdN)
            {
                // Line intersects triangle, check if segment does.
                Real QdN = -sign*diff.Dot(normal);
                Real extDdN = mSegment->Extent*DdN;
                if (-extDdN <= QdN && QdN <= extDdN)
                {
                    // Segment intersects triangle.
                    mIntersectionType = IT_POINT;
                    return true;
                }
                // else: |t| > extent, no intersection
            }
            // else: b1+b2 > 1, no intersection
        }
        // else: b2 < 0, no intersection
    }
    // else: b1 < 0, no intersection

    mIntersectionType = IT_EMPTY;
    return false;
}
void pTriangle::ComputeForce(Vector3 vair) {
    //find the tirangle velocity
    velocity = (p1->getVelocity() + p2->getVelocity() + p3->getVelocity()) / 3 ;
    //assume no air velocity for now
    Vector3 v = velocity - vair;
    
    Vector3 r1 = p1->getPosition();
    Vector3 r2 = p2->getPosition();
    Vector3 r3 = p3->getPosition();
    //find triangle unnormalized normal, n*
    Vector3 ra = (r2 - r1);
    Vector3 rb = (r3 - r1);
    Vector3 ncross;
    ncross.Cross(ra, rb);
    
    //constants
    float p = 1.225f;
    float cd = 1.225f;
    
    //force = -1/2 * p * |v|^2 * cd * a * n
    Vector3 v2an = ( (v.Mag()*v.Dot(ncross))/(2.0f*ncross.Mag()) ) * ncross;
    Vector3 aeroForce = (-1.0f/2.0f) * p * cd * v2an;
    aeroForce = aeroForce / 3;
    p1->ApplyForce(aeroForce);
    p2->ApplyForce(aeroForce);
    p3->ApplyForce(aeroForce);
    normal = ncross.Normalize();
}