IntersectionResult::Value OrientedBoundingBox::frustumIntersect(Frustum const& frustum) const
{
    bool intersecting = false;

    for (int i = 0; i < 6; i++)
    {
        IntersectionResult::Value result = planeIntersect(frustum.getPlane(i));

        if (result == IntersectionResult::OUTSIDE)
        {
            return IntersectionResult::OUTSIDE;
        }
        else if (result == IntersectionResult::INTERSECTING)
        {
            intersecting = true;
        }
    }

    if (intersecting)
    {
        return IntersectionResult::INTERSECTING;
    }

    return IntersectionResult::INSIDE;
}
示例#2
0
/*
CXXCircle::CXXCircle (const CXXCircle &oldOne) :
theAtomJ(oldOne.getAtomJ()),
theBallJ(oldOne.getBallJ()),
theParent(oldOne.getParent()),
centreOfSecondSphere(oldOne.getCentreOfSecondSphere()),
theNormal(oldOne.getNormal()),
radiusOfSecondSphere(oldOne.getRadiusOfSecondSphere()),
radiusOfSphere(oldOne.getRadiusOfSphere()),
centreOfCircle(oldOne.centreOfCircle),
centreToCircle(oldOne.getCentreToCircle()),
referenceUnitRadius(oldOne.getReferenceUnitRadius()),
radiusOfCircle(oldOne.getRadiusOfCircle()),
theNodes(oldOne.getNodes()),
nIntersectingCircles(oldOne.getNIntersectingCircles()),
completelyEaten(oldOne.getEaten())
{
	for (unsigned i=0; i<oldOne.getNNodes(); i++){
		theNodes[i].setParent(this);
	}
	theStarts.resize(oldOne.nSegments());
	theStops.resize(oldOne.nSegments());
	for (unsigned i=0; i<oldOne.nSegments(); i++){
		theStarts[i] = oldOne.start(i);
		theStops[i] = oldOne.stop(i);
	}
}
*/
int CXXCircle::meetsCircle(const CXXCircle &otherCircle, vector<CXXCoord, CXX::CXXAlloc<CXXCoord> > &nodeList) const{
	
	// check if there is an intersection between this circle and another circle
	// return 0 if there is intersection
	// 2 if the this circle is entirely swallowedd by the atom that generates the otherCircle, 
	// 1 if the converse of the above applies
	// and 3 otherwise
	
	CXXCoord intersectA, intersectB;
	
	// some simplifications:	rj - centreToCircle of current (this) arc circle
	//							rk - centreToCircle of newArc circle
	
	CXXCoord rj(getCentreToCircle());
	CXXCoord rk(otherCircle.getCentreToCircle());
	CXXCoord rjxrk;
	
	// following Totrovs vector match - plane intersection of the two circles.
	// PlaneIntersectioon points at intersection of two this- and new- circlePlanes
	// with plane spanned by the centre of the two VDW spheres and the centre of thisArc
	
	// some dummy variables
	
	double rjrk, rjSquared, rkSquared;
	double a, b, distSq, radiusOfSphereSq, x;
	
	rjSquared = rj*rj;
	rkSquared = rk*rk;
	rjrk = rj*rk;
	
	a = ((rjSquared - rjrk)*rkSquared)/(rjSquared*rkSquared - rjrk*rjrk);
	b = ((rkSquared - rjrk)*rjSquared)/(rjSquared*rkSquared - rjrk*rjrk);
	
	// with this now:
	CXXCoord planeIntersect((rj*a) + (rk*b));
	
	// if the distance between the intersection point of the three planes is closer then
	//the radius of the VDW + probe sphere, then the two circle of this arc and new arc intersect....
	
	// distance of intersectino point
	distSq = planeIntersect*planeIntersect;			
	radiusOfSphereSq = radiusOfSphere*radiusOfSphere;
	
	// distance of (VDW + probe) sphere of thisAtom = radiusOfSphere therefore:
	if (distSq < radiusOfSphereSq) {
		
		// the CIRCLES corresponding to the new and the current (old) arc cross each other
		// the crossingpoints of the two CIRCLES are the points where the line defined by the 
		// intersection of the two arcplanes cuts throught the new circle 
		
		// the intersection line is perpendicular the plane spanned by rj and rk - that is parallel to:
		rjxrk = rj ^ rk;
		rjxrk.normalise();
		
		//the intersection line is defined by this vector and one of its point - the planeIntersection vector:
		// => line planeIntersect + x*(rjxrk), x some real number
		// intersection points have x=+-0.5*length of the secante of circle therefore:
		x = sqrt(radiusOfSphereSq - distSq);
		
		rjxrk.scale(x);
		
		//We need to see whether the centreToCircle vectors of these circles indicate that the
		//corresponding torus is "behind" the centre of the first circle, or in front.  This determines
		//Whether the first or the second calculated intersection point represents a point to start drawing.
		//It boils down to a sort of parity thing.  Think about it !
		
		CXXCoord unitCentreToCircle(centreToCircle);
		unitCentreToCircle.normalise();
	    int forwardOne = (theNormal*unitCentreToCircle > 0.?1:-1);
		CXXCoord otherCircleUnitCentreToCircle(otherCircle.getCentreToCircle());
		otherCircleUnitCentreToCircle.normalise();
	    int forwardTwo = (otherCircle.getNormal()*otherCircleUnitCentreToCircle > 0.?1:-1);
		if (forwardOne*forwardTwo > 0){
			intersectA = planeIntersect+rjxrk;
			intersectB = planeIntersect-rjxrk;
		}
		else {
			intersectB = planeIntersect+rjxrk;
			intersectA = planeIntersect-rjxrk;
		}
		nodeList[0] = intersectA + getCentreOfSphere();
		nodeList[1] = intersectB + getCentreOfSphere();
		
		return 0;
		
	}
	else {
		//We get here if the two circles don't intersect
		//Now check whether this circle falls somewhere inside the
		//sphere indicated by the other circle.  If it does, then 
		//(given it doesn't intersect), it must *always* be inside
		// otherwise it must *always* be outside
		
		if (otherCircle.accIsBehind(getCentreOfCircle()) == 0) return 2;
		if(accIsBehind(otherCircle.getCentreOfCircle()) == 0) return 1;
		return 3;
	}
	
}
DistNorm ShapeCube::implicitIntersect(glm::vec4 pos, glm::vec4 direction, glm::mat4 shapeTransform, glm::vec2 *storeUV){
    glm::mat4 inverse = glm::inverse(shapeTransform); //to transform world coordinates into shape coordinates
    glm::vec4 shape_pos = inverse * pos;
    glm::vec4 shape_dir = inverse * direction;
    DistNorm gives;
    gives.dist = -1;
    glm::vec4 faces[] = {glm::vec4(.5, 0, 0, 1),
                         glm::vec4(-.5, 0, 0, 1),
                         glm::vec4(0, .5, 0, 1),
                         glm::vec4(0, -.5, 0, 1),
                         glm::vec4(0, 0, .5, 1),
                         glm::vec4(0, 0, -.5, 1)};
    for (int i = 0; i < 6; i++){
        glm::vec4 facePt = faces[i];
        glm::vec4 fNorm = glm::normalize(glm::vec4(glm::vec3(facePt), 0));
        float planehit = planeIntersect(shape_pos, shape_dir, facePt, fNorm);
        glm::vec4 intersect = shape_pos + shape_dir*planehit;
        if ((std::abs(intersect.x) - .5 < .001) && //idea: if the point is less than .5 from origin in each dimension, good;
                (std::abs(intersect.y) - .5 < .001) && //coordinate corresponding to face will always be .5 so don't worry
                (std::abs(intersect.z) - .5 < .001)){ //so, get magnitude, subtract .5, check < epsilon
            //ex: .25, .5, -.4 -> -.25, 0, -.1 all < epsilon

            if ((gives.dist > planehit && planehit >= 0) || gives.dist < 0){
                gives.dist = planehit;
                gives.norm = fNorm;
                if (storeUV){ //not null
                    float u, v;
                    switch (i){
                    case 0:
                        u = -intersect.z;
                        v = intersect.y;
                        break;
                    case 1:
                        u = intersect.z;
                        v = intersect.y;
                        break;
                    case 2:
                        u = intersect.x;
                        v = -intersect.z;
                        break;
                    case 3:
                        u = intersect.x;
                        v = intersect.z;
                        break;
                    case 4:
                        u = intersect.x;
                        v = intersect.y;
                        break;
                    case 5:
                        u = -intersect.x;
                        v = intersect.y;
                        break;
                    }
                    *storeUV = glm::vec2(u + .5f, v+.5f);
                }
            }
        }
    }

    if (gives.dist >= 0){
        gives.norm = glm::vec4(glm::normalize(glm::transpose(glm::inverse(glm::mat3(shapeTransform)))*glm::vec3(gives.norm)), 0); //put into world coords
        return gives;
    }else{
        return DistNorm{-1.f, glm::vec4(0, 0, 0, 0)}; //no intersect in front found
    }
}