Example #1
0
	bool Cylinder::intersects(const Vector3D& v0,const Vector3D& v1,Vector3D* intersection,Vector3D* normal) const
	{
	    if(!intersection) return false;

	    // mindist between line directed by tDir and line(v0 v1).
	    Vector3D u = v1 - v0; u.normalize();
	    if(tDirection == u || tDirection == -u) // colinear
	    {
	        float dist = dotProduct(tDirection,v0 - getTransformedPosition());

            Vector3D ext = v0 - (tDirection*dist + getTransformedPosition());
            float r = ext.getNorm(); ext = ext / r;

            if(r == radius) //intersection
            {
                *intersection = getTransformedPosition() + ext * radius;
                if(normal)
                    *normal = computeNormal(*intersection);
                return true;
            }
            else if(r < radius)
            {
                *intersection = getTransformedPosition() + tDirection * length*0.5f + ext * r;
                if(normal)
                    *normal = computeNormal(*intersection);
                return true;
            }
            return false;
	    }
	    else
	    {
	        Vector3D pp = getTransformedPosition() - v0, uv = u;
	        uv.crossProduct(tDirection);
			float dist = std::abs(dotProduct(pp,uv))/uv.getNorm();

	        float d = dotProduct(tDirection,v0 - getTransformedPosition());
            Vector3D ext = v0 - (tDirection*d + getTransformedPosition());
            float r = ext.getNorm();

	        float ah = std::cos(std::asin(dist/r))*r;
	        Vector3D h = v0 + u*ah;

	        if(contains(h)) // intersection
	        {
	            float offset = 3.1415926535897932384626433832795f*0.5f*dist/radius;
	            *intersection = h - offset * u;
	            if(normal)
                    *normal = computeNormal(*intersection);
	            return true;
	        }
	        return false;
	    }
	}
Example #2
0
	bool Plane::intersects(const Vector3D& v0,const Vector3D& v1,Vector3D* intersection,Vector3D* normal) const
	{
		float dist0 = dotProduct(tNormal,v0 - getTransformedPosition());
		float dist1 = dotProduct(tNormal,v1 - getTransformedPosition());

		if ((dist0 <= 0.0f) == (dist1 <= 0.0f)) // both points are on the same side
			return false;

		if (intersection != NULL)
		{
			if (dist0 <= 0.0f)
				dist0 = -dist0;
			else
				dist1 = -dist1;

			if (normal != NULL)
				*normal = tNormal;

			float ti = dist0 / (dist0 + dist1);

			Vector3D vDir = v1 - v0;
			float norm = vDir.getNorm();

			norm *= ti;
			ti = norm < APPROXIMATION_VALUE ? 0.0f : ti * (norm - APPROXIMATION_VALUE) / norm;

			vDir *= ti;
			*intersection = v0 + vDir;
		}

		return true;
	}
Example #3
0
	void Cylinder::moveAtBorder(Vector3D& v,bool inside) const
	{
	    float approx = inside ? -APPROXIMATION_VALUE : APPROXIMATION_VALUE;
        float dist = dotProduct(tDirection,v - getTransformedPosition());

		Vector3D ext = v - (tDirection*dist + getTransformedPosition());
		float r = ext.getNorm(); ext = ext / r;
		if(dist > length*0.5f)
		{
		    v -= tDirection * (dist - length*0.5f - approx);
		    if(r > radius)
                v -= ext*(r-radius-approx);
            return;
		}
		else if(dist < -length * 0.5f)
		{
            v += tDirection * (length*0.5f - dist - approx);
            if(r > radius)
                v -= ext*(r-radius-approx);
            return;
        }

        if(r > radius)
            v -= ext*(r-radius-approx);
        else
            v += ext*(radius-r+approx);
	}
Example #4
0
    bool Cylinder::contains(const Vector3D& v) const
    {
        float dist = dotProduct(tDirection,v - getTransformedPosition());

		Vector3D ext = v - (tDirection*dist + getTransformedPosition());
		float r = ext.getNorm();

		return dist <= length*0.5f && dist >= -length*0.5f && r <= radius;
    }
Example #5
0
    Vector3D Cylinder::computeNormal(const Vector3D& point) const
    {
        float dist = dotProduct(tDirection,point - getTransformedPosition());
        if(dist >= length*0.5f) return tDirection;
		if(dist <= -length*0.5f) return -tDirection;

		Vector3D ext = point - (tDirection*dist + getTransformedPosition());
		float r = ext.getNorm(); ext = ext / r;

		return ext;
    }
Example #6
0
	void Sphere::moveAtBorder(Vector3D& v,bool inside) const
	{
		Vector3D vDir = v - getTransformedPosition();
		float norm = vDir.getNorm();

		if (inside)
			vDir *= (radius + APPROXIMATION_VALUE) / norm;
		else
			vDir *= (radius - APPROXIMATION_VALUE) / norm;

		v = getTransformedPosition() + vDir;
	}
Example #7
0
	bool Sphere::intersects(const Vector3D& v0,const Vector3D& v1,Vector3D* intersection,Vector3D* normal) const
	{
		float r2 = radius * radius;
		float dist0 = getSqrDist(getTransformedPosition(),v0);
		float dist1 = getSqrDist(getTransformedPosition(),v1);

		if ((dist0 <= r2) == (dist1 <= r2))
			return false;

		if (intersection != NULL)
		{
			Vector3D vDir = v1 - v0;
			float norm = vDir.getNorm();

			float d = dotProduct(vDir,getTransformedPosition() - v0) / norm;
			float a = std::sqrt(r2 - dist0 + d * d);

			float ti;
			if (dist0 <= r2)
				ti = d - a;
			else
				ti = d + a;

			ti /= norm;

			if (ti < 0.0f) ti = 0.0f;
			if (ti > 1.0f) ti = 1.0f;

			norm *= ti;
			ti = norm < APPROXIMATION_VALUE ? 0.0f : ti * (norm - APPROXIMATION_VALUE) / norm;

			vDir *= ti;
			*intersection = v0 + vDir;

			if (normal != NULL)
			{
				if (dist0 <= r2)
					*normal = getTransformedPosition() - *intersection;
				else
					*normal = *intersection - getTransformedPosition();
				normal->normalize();
			}
		}

		return true;
	}
Example #8
0
	float Group::addParticles(const Vector3D& start,const Vector3D& end,const Vector3D& velocity,float step,float offset)
	{
		if ((step <= 0.0f)||(offset < 0.0f))
			return 0.0f;

		Vector3D displacement = end - start;
		float totalDist = displacement.getNorm();

		while(offset < totalDist)
		{
			Vector3D position = start;
			position += displacement * (offset / totalDist);
			addParticles(1,position,velocity,NULL,NULL);
			offset += step;
		}

		return offset - totalDist;
	}
Example #9
0
		if ((tEnter <= 0.0f)&&(tExit >= 1.0f))
			return false;

		if (intersection != NULL)
		{
			if (tEnter <= 0.0f)
			{
				tEnter = tExit;
				axis = (axis & 0xF0) >> 4;
			}
			else
				axis &= 0x0F;

			Vector3D vDir = v1 - v0;
			float norm = vDir.getNorm() * tEnter;
			tEnter = norm < APPROXIMATION_VALUE ? 0.0f : tEnter * (norm - APPROXIMATION_VALUE) / norm;

			vDir *= tEnter;
			*intersection = v0 + vDir;

			if (normal != NULL)
			{
				switch(axis)
				{
				case 0 :
					*normal = Vector3D(-1.0f,0.0f,0.0f);
					break;
				case 1 :
					*normal = Vector3D(0.0f,-1.0f,0.0f);
					break;