Ejemplo n.º 1
0
//////////////////////////////////////////////////////////////////////////
// faceCentre
MaVec3d MaAABB::faceCentre( BcU32 i ) const
{
	MaVec3d FaceCentre = centre();
	switch( i )
	{
	case FRONT:
	case BACK:
		FaceCentre += facePlane( i ).normal() * ( depth() * 0.5f );
		break;
	case TOP:
	case BOTTOM:
		FaceCentre += facePlane( i ).normal() * ( height() * 0.5f );
		break;
	case LEFT:
	case RIGHT:
		FaceCentre += facePlane( i ).normal() * ( width() * 0.5f );
		break;
	default:
		BcBreakpoint;
	}

	return FaceCentre;
}
Ejemplo n.º 2
0
void CalculateFacePlanes(const NpVector& orig, const NpVector& dir,
                         const NpVector vert[], 
                         double vd[], double vn[])
{
    static const int faceVertices[4][3] = { {3, 2, 1},
                                            {2, 3, 0},
                                            {1, 0, 3},
                                            {0, 1, 2} };

    for (unsigned int i = 0; i < 4; ++i)  {
        NpPlane facePlane(vert[faceVertices[i][0]],
                          vert[faceVertices[i][1]],
                          vert[faceVertices[i][2]]);
        vd[i] = dir * facePlane.n;
        vn[i] = (orig * facePlane.n) + facePlane.d;
    }
}
Ejemplo n.º 3
0
//////////////////////////////////////////////////////////////////////////
// rayIntersect
BcBool MaAABB::lineIntersect( const MaVec3d& Start, const MaVec3d& End, MaVec3d* pIntersectionPoint, MaVec3d* pIntersectionNormal ) const
{
	// Planes. Screw it.
	// Totally inoptimal.
	MaPlane Planes[6];
	MaVec3d Intersects[6];
	BcF32 Distance;
	for( BcU32 i = 0; i < 6; ++i )
	{
		Planes[i] = facePlane( i );
		if( !Planes[i].lineIntersection( Start, End, Distance, Intersects[i] ) )
		{
			Intersects[i] = MaVec3d( 1e24f, 1e24f, 1e24f );
		}
	}

	// Reject classified and find nearest.
	BcF32 Nearest = 1e24f;
	BcU32 iNearest = BcErrorCode;

	for( BcU32 i = 0; i < 6; ++i )
	{
		// For every point...
		// ...check against planes.
		BcBool Valid = BcTrue;
		for( BcU32 j = 0; j < 6; ++j )
		{
			if( Planes[j].classify( Intersects[i] ) == MaPlane::bcPC_FRONT )
			{
				Valid = BcFalse;
				break;
			}
		}

		// If its valid, check distance.
		if( Valid )
		{
			BcF32 Distance = ( Start - Intersects[i] ).magnitudeSquared();

			if( Distance < Nearest )
			{
				Nearest = Distance;
				iNearest = i;
			}
		}
	}

	//
	if( iNearest != BcErrorCode )
	{
		if( pIntersectionPoint != NULL )
		{
			*pIntersectionPoint = Intersects[ iNearest ];
		}

		if( pIntersectionNormal != NULL )
		{
			*pIntersectionNormal = Planes[ iNearest ].normal();
		}

		return BcTrue;
	}
	return BcFalse;
}
Ejemplo n.º 4
0
const Zeni::Point3f Utils::getFaceLineSegmentIntersection(const Zeni::Collision::Line_Segment &lineSegment, const Zeni::Point3f &p1, const Zeni::Point3f &p2, const Zeni::Point3f &p3) {
	// Interpolate along line segment to the interpolation value returned by the collision
	Zeni::Collision::Plane facePlane(p1, getSurfaceNormal(p1, p2, p3));
	return lineSegment.get_end_point_a().interpolate_to(lineSegment.nearest_point(facePlane).second, lineSegment.get_end_point_b());
}
Ejemplo n.º 5
0
bool RayTetraHaines(
    const NpVector& orig, const NpVector& dir,
    const NpVector vert[], 
    int& enterFace, int& leaveFace,
    NpVector& enterPoint, NpVector& leavePoint,
    double& uEnter1, double& uEnter2, double& uLeave1, double& uLeave2,
    double& tEnter, double& tLeave)
{
    static const int faceVertices[4][3] = { {3, 2, 1},
                                            {2, 3, 0},
                                            {1, 0, 3},
                                            {0, 1, 2} };

    tEnter = -NpInf;
    tLeave = NpInf;

    enterFace = -1;   // Keep the compiler happy about
    leaveFace = -1;   // uninitialized variables

    // Test each plane in polyhedron
    for (unsigned int i = 0; i < 4; ++i)  {
        // Calculate face equation, faceNormal*(x,y,z) + faceD;
        NpPlane facePlane(vert[faceVertices[i][0]],
                          vert[faceVertices[i][1]],
                          vert[faceVertices[i][2]]);

        // Compute intersection point T and sidedness
        double vd = dir * facePlane.n;
        double vn = (orig * facePlane.n) + facePlane.d;

        if (vd == 0.0)  {
            // ray is parallel to plane - 
            // check if ray origin is inside plane's half-space
            if (vn > 0.0)  {
                // ray origin is outside half-space
                return false;
            }
        }
        else  {
            // ray not parallel - get distance to plane
            double t = -vn / vd;
            if (vd < 0.0)  {
                // front face - T is a near point
                if (t > tLeave)  {
                    return false;
                }
                if (t > tEnter)  {
                    // hit near face, update normal
                    tEnter = t;
                    enterFace = i;
                }
            }
            else  {
                // back face - T is a far point
                if (t < tEnter)  {
                    return false;
                }
                if (t < tLeave)  {
                    // hit far face, update normal
                    tLeave = t;
                    leaveFace = i;
                }
            }
        }
    }

    // Handle degenerate tetrahedra
    if (enterFace == -1)  {
        return false;
    }
    
    // survived all tests, ray intersects tetrahedron
    enterPoint = orig + tEnter * dir;
    leavePoint = orig + tLeave * dir;

    // Calculate barycentric coordinates of enterPoint
    const NpVector& aEnter = vert[faceVertices[enterFace][0]];

    NpVector abEnter = vert[faceVertices[enterFace][1]] - aEnter;
    NpVector acEnter = vert[faceVertices[enterFace][2]] - aEnter;
    NpVector apEnter = enterPoint - aEnter;
    NpVector normalEnter = abEnter ^ acEnter;
    double invLengthEnter = 1.0 / normalEnter.Measure2();

    uEnter1 = invLengthEnter * ((apEnter ^ acEnter) * normalEnter);
    uEnter2 = invLengthEnter * ((abEnter ^ apEnter) * normalEnter);
    
    // Calculate barycentric coordinates of leavePoint
    const NpVector& aLeave = vert[faceVertices[leaveFace][0]];

    NpVector abLeave = vert[faceVertices[leaveFace][1]] - aLeave;
    NpVector acLeave = vert[faceVertices[leaveFace][2]] - aLeave;
    NpVector apLeave = leavePoint - aLeave;
    NpVector normalLeave = abLeave ^ acLeave;
    double invLengthLeave = 1.0 / normalLeave.Measure2();

    uLeave1 = invLengthLeave * ((apLeave ^ acLeave) * normalLeave);
    uLeave2 = invLengthLeave * ((abLeave ^ apLeave) * normalLeave);
    
    return true;
}