Ejemplo n.º 1
0
bool dgCollisionConvexHull::OOBBTest (const dgMatrix& matrix, const dgCollisionConvex* const shape, void* const cacheOrder) const
{
	bool ret;
	_ASSERTE (cacheOrder);

	ret = dgCollisionConvex::OOBBTest (matrix, shape, cacheOrder);
	if (ret) {
		const dgConvexSimplexEdge* const* faceArray = m_faceArray;
		dgCollisionBoundPlaneCache* const cache = (dgCollisionBoundPlaneCache*)cacheOrder;

		for (dgInt32 i = 0; i < dgInt32 (sizeof (cache->m_planes) / sizeof (dgPlane)); i ++) {
			dgFloat32 dist;
			const dgPlane& plane = cache->m_planes[i];
			if ((plane % plane) > dgFloat32 (0.0f)) {
				dgVector dir (matrix.UnrotateVector(plane.Scale (-1.0f)));
				dir.m_w = dgFloat32 (0.0f);
				dgVector p (matrix.TransformVector (shape->SupportVertex(dir)));
				dist = plane.Evalue (p);
				if (dist > dgFloat32 (0.1f)){
					return false;
				} 
			}
		}

		for (dgInt32 i = 0; i < m_boundPlanesCount; i ++) {
			dgInt32 i0;
			dgInt32 i1;
			dgInt32 i2;
			dgFloat32 dist;

			const dgConvexSimplexEdge* const face = faceArray[i];
			i0 = face->m_prev->m_vertex;
			i1 = face->m_vertex;
			i2 = face->m_next->m_vertex;
			const dgVector& p0 = m_vertex[i0];

			dgVector normal ((m_vertex[i1] - p0) * (m_vertex[i2] - p0));
			normal = normal.Scale (dgFloat32 (1.0f) / dgSqrt (normal % normal));

			dgVector dir (matrix.UnrotateVector(normal.Scale (-1.0f)));
			dir.m_w = dgFloat32 (0.0f);
			dgVector p (matrix.TransformVector (shape->SupportVertex(dir)));

			//_ASSERTE ((normal % (m_boxOrigin - p0)) < 0.0f);
			dist = normal % (p - p0);
			if (dist > dgFloat32 (0.1f)){
				for (dgInt32 j = 0; j < (dgInt32 (sizeof (cache->m_planes) / sizeof (dgPlane)) - 1); j ++) {
					cache->m_planes[j + 1] = cache->m_planes[j];
				}
				cache->m_planes[1] = dgPlane (normal, - (normal % p0));
				return false;
			} 
		}
	}
	return ret;
}
void dgCollisionConvexPolygon::BeamClipping (const dgVector& origin, dgFloat32 dist)
{
    dgPlane planes[4];
    dgVector points[sizeof (m_localPoly) / sizeof (m_localPoly[0]) + 8];
    dgClippedFaceEdge clippedFace [2 * sizeof (m_localPoly) / sizeof (m_localPoly[0]) + 8];

    dgVector dir (m_localPoly[1] - m_localPoly[0]);
    dgAssert (dir.m_w == dgFloat32 (0.0f));
    dgAssert ((dir % dir) > dgFloat32 (1.0e-8f));
    dir = dir.CompProduct4 (dir.InvMagSqrt());

    dgFloat32 distH = origin.DotProduct4(dir).GetScalar();
    planes[0] = dgPlane (dir, dist - distH);
    planes[2] = dgPlane (dir.CompProduct4 (dgVector::m_negOne), dist + distH);

    dir = m_normal * dir;
    dgFloat32 distV = origin.DotProduct4(dir).GetScalar();
    planes[1] = dgPlane (dir, dist - distV);
    planes[3] = dgPlane (dir.CompProduct4 (dgVector::m_negOne), dist + distV);

    for (dgInt32 i = 0; i < m_count; i ++) {
        dgInt32 j = i << 1;
        dgAssert (j < sizeof (clippedFace) / sizeof (clippedFace[0]));

        points[i] = m_localPoly[i];

        clippedFace[j + 0].m_twin = &clippedFace[j + 1];
        clippedFace[j + 0].m_next = &clippedFace[j + 2];
        clippedFace[j + 0].m_incidentVertex = i;
        clippedFace[j + 0].m_incidentNormal = m_adjacentFaceEdgeNormalIndex[i];

        clippedFace[j + 1].m_twin = &clippedFace[j + 0];
        clippedFace[j + 1].m_next = &clippedFace[j - 2];
        clippedFace[j + 1].m_incidentVertex = i + 1;
        clippedFace[j + 1].m_incidentNormal = -1;
    }

    clippedFace[1].m_next = &clippedFace[m_count * 2 - 2 + 1];
    dgAssert ((m_count * 2 - 2) >= 0);
    clippedFace[m_count * 2 - 2].m_next = &clippedFace[0];
    clippedFace[m_count * 2 - 2 + 1].m_incidentVertex = 0;

    dgInt32 edgeCount = m_count * 2;
    dgInt32 indexCount = m_count;
    dgClippedFaceEdge* first = &clippedFace[0];
    for (dgInt32 i = 0; i < 4; i ++) {
        const dgPlane& plane = planes[i];

        dgInt32 conectCount = 0;
        dgClippedFaceEdge* connect[2];
        dgClippedFaceEdge* ptr = first;
        dgClippedFaceEdge* newFirst = first;
        dgFloat32 test0 = plane.Evalue(points[ptr->m_incidentVertex]);
        do {
            dgFloat32 test1 = plane.Evalue(points[ptr->m_next->m_incidentVertex]);

            if (test0 > dgFloat32 (1.0e-2f)) {
                if (test1 <= dgFloat32 (-1.0e-2f)) {
                    const dgVector& p0 = points[ptr->m_incidentVertex];
                    const dgVector& p1 = points[ptr->m_next->m_incidentVertex];
                    dgVector dp (p1 - p0);
                    points[indexCount] = p0 - dp.Scale4 (test0 / dp.DotProduct4(plane).GetScalar());

                    dgClippedFaceEdge* const newEdge = &clippedFace[edgeCount];
                    newEdge->m_twin = newEdge + 1;
                    newEdge->m_twin->m_twin = newEdge;

                    newEdge->m_twin->m_incidentNormal = ptr->m_incidentNormal;
                    newEdge->m_incidentNormal = ptr->m_incidentNormal;

                    newEdge->m_incidentVertex = indexCount;
                    newEdge->m_twin->m_incidentVertex = ptr->m_next->m_incidentVertex;
                    ptr->m_twin->m_incidentVertex = indexCount;

                    newEdge->m_next = ptr->m_next;
                    ptr->m_next->m_twin->m_next = newEdge->m_twin;
                    newEdge->m_twin->m_next = ptr->m_twin;
                    ptr->m_next = newEdge;

                    connect[conectCount] = ptr;
                    conectCount ++;
                    indexCount ++;
                    edgeCount += 2;
                    ptr = newEdge;
                }
            } else {
                if (test1 > dgFloat32 (1.0e-2f)) {
                    newFirst = ptr->m_next;

                    const dgVector& p0 = points[ptr->m_incidentVertex];
                    const dgVector& p1 = points[ptr->m_next->m_incidentVertex];
                    dgVector dp (p1 - p0);
                    points[indexCount] = p0 - dp.Scale4 (test0 / dp.DotProduct4(plane).GetScalar());

                    dgClippedFaceEdge* const newEdge = &clippedFace[edgeCount];
                    newEdge->m_twin = newEdge + 1;
                    newEdge->m_twin->m_twin = newEdge;

                    newEdge->m_twin->m_incidentNormal = ptr->m_incidentNormal;;
                    newEdge->m_incidentNormal = ptr->m_incidentNormal;

                    newEdge->m_incidentVertex = indexCount;
                    newEdge->m_twin->m_incidentVertex = ptr->m_next->m_incidentVertex;
                    ptr->m_twin->m_incidentVertex = indexCount;

                    newEdge->m_next = ptr->m_next;
                    ptr->m_next->m_twin->m_next = newEdge->m_twin;
                    newEdge->m_twin->m_next = ptr->m_twin;
                    ptr->m_next = newEdge;

                    connect[conectCount] = ptr;
                    conectCount ++;
                    indexCount ++;
                    edgeCount += 2;

                    ptr = newEdge;
                }
            }


            test0 = test1;
            ptr = ptr->m_next;
        } while (ptr != first);

        if(conectCount > 1) {
            first = newFirst;
            dgAssert (conectCount == 2);

            dgClippedFaceEdge* const newEdge = &clippedFace[edgeCount];
            newEdge->m_twin = newEdge + 1;
            newEdge->m_twin->m_twin = newEdge;

            newEdge->m_incidentNormal = m_faceNormalIndex;;
            newEdge->m_incidentVertex = connect[0]->m_next->m_incidentVertex;
            newEdge->m_twin->m_next = connect[0]->m_next;
            connect[0]->m_next = newEdge;

            newEdge->m_twin->m_incidentNormal = m_faceNormalIndex;;
            newEdge->m_twin->m_incidentVertex = connect[1]->m_next->m_incidentVertex;
            newEdge->m_next = connect[1]->m_next;
            connect[1]->m_next = newEdge->m_twin;

            edgeCount += 2;
        }
    }


    dgClippedFaceEdge* ptr = first;
    do {
        dgVector dist (points[ptr->m_next->m_incidentVertex] - points[ptr->m_incidentVertex]);
        dgFloat32 error = dist % dist;
        if (error < dgFloat32 (1.0e-6f)) {
            ptr->m_next = ptr->m_next->m_next;
            first = ptr;
        }
        ptr = ptr->m_next;
    } while (ptr != first);


    dgInt32 count = 0;
    dgInt32 isConvexCap = 0;
    m_adjacentFaceEdgeNormalIndex = &m_clippEdgeNormal[0];
    do {
        m_clippEdgeNormal[count] = ptr->m_incidentNormal;
        isConvexCap |= (ptr->m_incidentNormal - m_faceNormalIndex);
        m_localPoly[count] = points[ptr->m_incidentVertex];
        count ++;
        ptr = ptr->m_next;
    } while (ptr != first);

    m_count = count;
}