Example #1
0
bool HeightFieldPrimitive::Intersect(const Ray &ray, Intersection *in) const {

	float tHit, rayEpsilon;
	if (TriangleIntersect(ray, pts, &tHit, &rayEpsilon) || 
		TriangleIntersect(ray, &(pts[1]), &tHit, &rayEpsilon)) {

		in->tHit = tHit;
		in->primitive = this;
		in->rayEpsilon = rayEpsilon;
		return true;
	} 
	
	return false;
}
Example #2
0
bool Intersect(const Ray &ray, RayHit& rayHit, BVHAccelArrayNode* bvhTree, Triangle *triangles,
		Point *vertices) {


	rayHit.t = INFINITY;
	rayHit.index = 0xffffffffu;
	unsigned int currentNode = 0; // Root Node
	unsigned int stopNode = bvhTree[0].skipIndex; // Non-existent
	bool hit = false;
	RayHit triangleHit;

	while (currentNode < stopNode) {
		if (BBox_IntersectP(bvhTree[currentNode].bbox, ray, NULL, NULL)) {
			if (bvhTree[currentNode].primitive != 0xffffffffu) {
				//float tt, b1, b2;
				Triangle t = triangles[bvhTree[currentNode].primitive];
				if (TriangleIntersect(&t,ray, vertices, &triangleHit)) {
					hit = true; // Continue testing for closer intersections
					if (triangleHit.t < rayHit.t) {
						rayHit.t = triangleHit.t;
						rayHit.b1 = triangleHit.b1;
						rayHit.b2 = triangleHit.b2;
						rayHit.index = bvhTree[currentNode].primitive;
					}
				}
			}

			currentNode++;
		} else
			currentNode = bvhTree[currentNode].skipIndex;
	}

	return hit;
}
Example #3
0
//-------------------------------------------------------------------------------
// @ ::CoplanarTriangleIntersect()
//-------------------------------------------------------------------------------
// Helper for TriangleIntersect()
//
// This projects the two triangles down to 2D, maintaining the largest area by
// dropping the dimension where the normal points the farthest.
//-------------------------------------------------------------------------------
inline bool CoplanarTriangleIntersect( const IvVector3& P0,
                                       const IvVector3& P1, const IvVector3& P2,
                                       const IvVector3& Q0, const IvVector3& Q1,
                                       const IvVector3& Q2, const IvVector3& planeNormal )
{
    IvVector3 absNormal( ::IvAbs(planeNormal.x), ::IvAbs(planeNormal.y),
                         ::IvAbs(planeNormal.z) );

    IvVector2 projP0, projP1, projP2;
    IvVector2 projQ0, projQ1, projQ2;

    // if x is direction of largest magnitude
    if ( absNormal.x > absNormal.y && absNormal.x >= absNormal.z )
    {
        projP0.Set( P0.y, P0.z );
        projP1.Set( P1.y, P1.z );
        projP2.Set( P2.y, P2.z );
        projQ0.Set( Q0.y, Q0.z );
        projQ1.Set( Q1.y, Q1.z );
        projQ2.Set( Q2.y, Q2.z );
    }
    // if y is direction of largest magnitude
    else if ( absNormal.y > absNormal.x && absNormal.y >= absNormal.z )
    {
        projP0.Set( P0.x, P0.z );
        projP1.Set( P1.x, P1.z );
        projP2.Set( P2.x, P2.z );
        projQ0.Set( Q0.x, Q0.z );
        projQ1.Set( Q1.x, Q1.z );
        projQ2.Set( Q2.x, Q2.z );
    }
    // z is the direction of largest magnitude
    else
    {
        projP0.Set( P0.x, P0.y );
        projP1.Set( P1.x, P1.y );
        projP2.Set( P2.x, P2.y );
        projQ0.Set( Q0.x, Q0.y );
        projQ1.Set( Q1.x, Q1.y );
        projQ2.Set( Q2.x, Q2.y );
    }

    return TriangleIntersect( projP0, projP1, projP2, projQ0, projQ1, projQ2 );
}
Example #4
0
//線分と三角形ポリゴンとの衝突判定
bool CCollision::IntersectTriangleRay(CVector3D *corss,const CVector3D &p1, const CVector3D &p2,const CVector3D &v0, const CVector3D &v1, const CVector3D &v2,float *pt ) {
	CVector3D e1, e2,normal,pv1,pv2;

	e1 = v1 - v0;
	e2 = v2 - v0;

	//面の法線を求める
	normal = CVector3D::Cross(e1, e2).GetNormalize();

	//始点からポリゴン上のある地点(どこでもいい)へのベクトル
	pv1 = p1-v0;
	//終点からポリゴン上のある地点(どこでもいい)へのベクトル
	pv2 = p2-v0;

	//ポリゴンの法線との内積を求める
	float d1 = CVector3D::Dot(pv1,normal);
	float d2 = CVector3D::Dot(pv2,normal);

	//ポリゴンを貫通していない
	if(d1*d2>0) return false;

	//始点からポリゴンまでの距離と線分の長さの比率を求める
	//接地地点を出すのに使用する
	float t = d1/(d1-d2);
	if( *pt < t ) return false;

	//裏から貫通している場合は衝突していないことにする
	if(t<0) return false;

	//線分と平面の接地地点を求める
	CVector3D c = p1+(p2-p1)*t;

	//接地地点が三角形ポリゴン上か調べる
	if(!TriangleIntersect(c,v0,v1,v2,normal)) return false;
	
	if(pt) *pt = t;
	if(corss) *corss = c;

	return true;
}
Example #5
0
bool CCollision::CollisionTriangleCapsule(const CVector3D &v0,const CVector3D &v1,const CVector3D &v2,const CVector3D &top,const CVector3D &bottom,float radius,CVector3D *cross,float *length ){
	
	CVector3D V(top-bottom);

	CVector3D  VP;
	float Dist = 1e10;

	//ポリゴンの法線を求める
	CVector3D N(CVector3D::Cross(v1 - v0, v2 - v0).GetNormalize());

	//始点からポリゴン上のある地点(どこでもいい)へのベクトル
	CVector3D PV1 = top-v0;
	//終点からポリゴン上のある地点(どこでもいい)へのベクトル
	CVector3D PV2 = bottom-v0;

	//ポリゴンの法線との内積を求める
	float d1 = CVector3D::Dot(PV1,N);
	float d2 = CVector3D::Dot(PV2,N);

	if(d1*d2<0) {
		//貫通している場合は線とポリゴンの判定を行う
		if(IntersectTriangleRay(cross,top+CVector3D(0,radius,0),bottom+CVector3D(0,-radius,0),v0,v1,v2,&Dist)) {
			if(length) {
				//貫通点までの距離を求める
				float lt = (*cross - top).LengthSq();
				float lb = (*cross - bottom).LengthSq();
				if(lt<lb) *length = sqrt(lt);
				else *length = sqrt(lb);
			}
			return true;
		}
	}

	d1=abs(d1);
	d2=abs(d2);
	//平面上の点との最短地点を求める
	CVector3D C1(top-N*d1);
	CVector3D C2(bottom-N*d2);
	//点が平面上にない場合は無効、後の辺との接触で調べる
	if(!TriangleIntersect(C1,v0,v1,v2,N)) d1=1e10;
	if(!TriangleIntersect(C2,v0,v1,v2,N)) d2=1e10;


	//面との距離が近い点の距離を選択
	Dist = (d1<d2) ? d1:d2; 
	if(Dist<=radius) {
		//追加
		if(length) *length = Dist;
		return true;
	}
	

	//各辺との距離を求める
	Dist = min(min(DistanceLine(v0,v1,top,bottom),DistanceLine(v1,v2,top,bottom)),DistanceLine(v2,v0,top,bottom));

	if(length) *length = Dist;

    return (Dist<=radius);
	




}
Example #6
0
//-----------------------------------------------------------------------------
bool CCollision::CollisionTriangleSphere( const CVector3D &v0,const CVector3D &v1,const CVector3D &v2,const CVector3D &center,float radius ,CVector3D *cross,float *length)
{
   
     CVector3D V1(v1-v0);
	 CVector3D V2(v2-v1);
	 CVector3D N(CVector3D::Cross(V1,V2).GetNormalize());
	 
	 CVector3D V = center - v0;
	 //平面と点の距離を求める
	 float Dist = CVector3D::Dot(V,N);
  
	//球の半径より離れている場合は接触無し
	 if(abs(Dist) > radius) return false;

	 //点から平面上に垂直に下ろした地点を求める
	 CVector3D Point =  center - ( N * Dist );
	 
	 
	 //上記の点が三角形ポリゴン内なら接触している
	 if(TriangleIntersect( Point, v0, v1, v2 , N)) {
		if(cross) *cross = Point;
		if(length) *length = Dist;
		return true;
	}



	 //各辺に球がかすっている可能性がある
	 //1辺ごとに球と辺の最短距離を求める

	 //最短距離
	 float l;
	 //最短接触地点
	 CVector3D c;
	 
	 //距離比較用
	 float LengthSq;



	 //辺1(v0→v1)
	 Point = PointOnLineSegmentNearestPoint( v0, v1, center );
	 LengthSq = (center - Point).LengthSq();
	 l  = LengthSq;
	 c = Point;

	 //辺2(v1→v2)
	 Point = PointOnLineSegmentNearestPoint( v1, v2, center );
	 LengthSq = (center - Point).LengthSq();
	 if(l>LengthSq) {
		 l = LengthSq;
		 c = Point;
	 }
	 
	 //辺3(v2→v0)
	 Point = PointOnLineSegmentNearestPoint( v2, v0, center );
	 LengthSq = (center - Point).LengthSq();
	 if(l>LengthSq) {
		 l = LengthSq;
		 c = Point;
	 }


	 l = sqrt(l);
	 //最短距離を確定
	 if(length) *length = l;
	 //最短地点を確定
	 if(cross) *cross = c;
	
    return (l<=radius);
}
bool Heightfield2::Intersect(const Ray &r, float *tHit, float *rayEpsilon, DifferentialGeometry *dg) const{
    Ray ray;
    (*WorldToObject)(r, &ray);

    float rayT;
    if(bounds.Inside(ray(ray.mint)))
        rayT = ray.mint;
    else if(!bounds.IntersectP(ray, &rayT))
        return false;
    Point gridIntersect = ray(rayT);
    
    // Set up 2D DDA for ray
    float NextCrossingT[2], DeltaT[2];
    int Step[2], Out[2], Pos[2];
    for (int axis = 0; axis < 2; ++axis) {
        // Compute current voxel for axis
        Pos[axis] = posToVoxel(gridIntersect, axis);
        if (ray.d[axis] >= 0) {
            // Handle ray with positive direction for voxel stepping
            NextCrossingT[axis] = rayT +
                (voxelToPos(Pos[axis]+1, axis) - gridIntersect[axis]) / ray.d[axis];
            DeltaT[axis] = width[axis] / ray.d[axis];
            Step[axis] = 1;
            Out[axis] = nVoxels[axis];
        }
        else {
            // Handle ray with negative direction for voxel stepping
            NextCrossingT[axis] = rayT +
                (voxelToPos(Pos[axis], axis) - gridIntersect[axis]) / ray.d[axis];
            DeltaT[axis] = -width[axis] / ray.d[axis];
            Step[axis] = -1;
            Out[axis] = -1;
        }
    }

    // Walk ray through voxel grid
    bool hitSomething = false;
    int index[3];
    for (;;) {

        // Check for intersection in current voxel and advance to next
        index[0] = Pos[0] + Pos[1]*nx;
        index[1] = Pos[0]+1 + Pos[1]*nx;
        index[2] = Pos[0]+1 + (Pos[1]+1)*nx;
        hitSomething |= TriangleIntersect(r, tHit, rayEpsilon, dg, index);
        
        index[1] = Pos[0]+1 + (Pos[1]+1)*nx;
        index[2] = Pos[0] + (Pos[1]+1)*nx;
        hitSomething |= TriangleIntersect(r, tHit, rayEpsilon, dg, index);
        if(hitSomething) return hitSomething;

        // Advance to next voxel
        // Find _stepAxis_ for stepping to next voxel
        int stepAxis = (NextCrossingT[0] < NextCrossingT[1])? 0 : 1;
        Pos[stepAxis] += Step[stepAxis];
        if (Pos[stepAxis] == Out[stepAxis])
            break;
        NextCrossingT[stepAxis] += DeltaT[stepAxis];
    }
    return hitSomething;
}