Пример #1
0
dgFloat64 Determinant4x4 (const dgFloat64 matrix[4][4], dgFloat64* const error)
{
	dgFloat64 sign = dgFloat64 (1.0f);
	dgFloat64 det = dgFloat64 (0.0f);
	dgFloat64 accError = dgFloat64 (0.0f); 
	for (dgInt32 i = 0; i < 4; i ++)  {
		dgFloat64 cofactor[3][3];
		for (dgInt32 j = 0; j < 3; j ++) {
			dgInt32 k0 = 0;
			for (dgInt32 k = 0; k < 4; k ++) {
				if (k != i) {
					cofactor[j][k0] = matrix[j][k];
					k0 ++;
				}
			}
		}

		dgFloat64 parcialError;
		dgFloat64 minorDet = Determinant3x3 (cofactor, &parcialError);
		accError +=  parcialError * Absolute (matrix[3][i]);
		det += sign * minorDet * matrix[3][i];
		sign *= dgFloat64 (-1.0f);
	}

	*error = accError;
	return det;
}
Пример #2
0
dgFloat64 dgConvexHull4dTetraherum::Evalue (const dgHullVector* const pointArray, const dgBigVector& point) const
{
	const dgBigVector &p0 = pointArray[m_faces[0].m_index[0]];
	const dgBigVector &p1 = pointArray[m_faces[0].m_index[1]];
	const dgBigVector &p2 = pointArray[m_faces[0].m_index[2]];
	const dgBigVector &p3 = pointArray[m_faces[0].m_index[3]];

	dgFloat64 matrix[4][4];
	for (dgInt32 i = 0; i < 4; i ++) {
		matrix[0][i] = p1[i] - p0[i];
		matrix[1][i] = p2[i] - p0[i];
		matrix[2][i] = p3[i] - p0[i];
		matrix[3][i] = point[i] - p0[i];
	}

	dgFloat64 error;
	dgFloat64 det = Determinant4x4 (matrix, &error);
	dgFloat64 precision  = dgFloat64 (1.0f) / dgFloat64 (1<<24);
	dgFloat64 errbound = error * precision; 
	if (fabs(det) > errbound) {
		return det;
	}

	dgGoogol exactMatrix[4][4];
	for (dgInt32 i = 0; i < 4; i ++) {
		exactMatrix[0][i] = dgGoogol(p1[i]) - dgGoogol(p0[i]);
		exactMatrix[1][i] = dgGoogol(p2[i]) - dgGoogol(p0[i]);
		exactMatrix[2][i] = dgGoogol(p3[i]) - dgGoogol(p0[i]);
		exactMatrix[3][i] = dgGoogol(point[i]) - dgGoogol(p0[i]);
	}
	return Determinant4x4(exactMatrix);
}
Пример #3
0
void dgConvexHull4d::TessellateTriangle (dgInt32 level, const dgVector& p0, const dgVector& p1, const dgVector& p2, dgInt32& count, dgBigVector* const ouput, dgInt32& start) const
{
	if (level) {
		dgAssert (dgAbsf (p0 % p0 - dgFloat32 (1.0f)) < dgFloat32 (1.0e-4f));
		dgAssert (dgAbsf (p1 % p1 - dgFloat32 (1.0f)) < dgFloat32 (1.0e-4f));
		dgAssert (dgAbsf (p2 % p2 - dgFloat32 (1.0f)) < dgFloat32 (1.0e-4f));
		dgVector p01 (p0 + p1);
		dgVector p12 (p1 + p2);
		dgVector p20 (p2 + p0);

		p01 = p01.Scale3 (dgRsqrt(p01 % p01));
		p12 = p12.Scale3 (dgRsqrt(p12 % p12));
		p20 = p20.Scale3 (dgRsqrt(p20 % p20));

		dgAssert (dgAbsf (p01 % p01 - dgFloat32 (1.0f)) < dgFloat32 (1.0e-4f));
		dgAssert (dgAbsf (p12 % p12 - dgFloat32 (1.0f)) < dgFloat32 (1.0e-4f));
		dgAssert (dgAbsf (p20 % p20 - dgFloat32 (1.0f)) < dgFloat32 (1.0e-4f));

		TessellateTriangle  (level - 1, p0,  p01, p20, count, ouput, start);
		TessellateTriangle  (level - 1, p1,  p12, p01, count, ouput, start);
		TessellateTriangle  (level - 1, p2,  p20, p12, count, ouput, start);
		TessellateTriangle  (level - 1, p01, p12, p20, count, ouput, start);

	} else {
		dgBigPlane n (p0, p1, p2);
		n = n.Scale (dgFloat64(1.0f) / sqrt (n % n));
		n.m_w = dgFloat64(0.0f);
		ouput[start] = n;
		start += 8;
		count ++;
	}
}
Пример #4
0
dgFloat64 dgSymmetricBiconjugateGradientSolve::Solve (dgInt32 size, dgFloat64 tolerance, dgFloat64* const x, const dgFloat64* const b) const
{
	dgStack<dgFloat64> bufferR0(size);
	dgStack<dgFloat64> bufferP0(size);
	dgStack<dgFloat64> matrixTimesP0(size);
	dgStack<dgFloat64> bufferConditionerInverseTimesR0(size);

	dgFloat64* const r0 = &bufferR0[0];
	dgFloat64* const p0 = &bufferP0[0];
	dgFloat64* const MinvR0 = &bufferConditionerInverseTimesR0[0];
	dgFloat64* const matrixP0 = &matrixTimesP0[0];

	MatrixTimeVector (matrixP0, x);
	Sub(size, r0, b, matrixP0);
	bool continueExecution = InversePrecoditionerTimeVector (p0, r0);

	dgInt32 iter = 0;
	dgFloat64 num = DotProduct (size, r0, p0);
	dgFloat64 error2 = num;
	for (dgInt32 j = 0; (j < size) && (error2 > tolerance) && continueExecution; j ++) {

		MatrixTimeVector (matrixP0, p0);
		dgFloat64 den = DotProduct (size, p0, matrixP0);

		dgAssert (fabs(den) > dgFloat64 (0.0f));
		dgFloat64 alpha = num / den;

		ScaleAdd (size, x, x, alpha, p0);
        if ((j % 50) != 49) {
		    ScaleAdd (size, r0, r0, -alpha, matrixP0);
        } else {
            MatrixTimeVector (matrixP0, x);
            Sub(size, r0, b, matrixP0);
        }

//dgUnsigned64 xxx0 = dgGetTimeInMicrosenconds();
		continueExecution = InversePrecoditionerTimeVector (MinvR0, r0);
//xxx0 = dgGetTimeInMicrosenconds() - xxx0;
//dgTrace (("%d\n", dgUnsigned64 (xxx0)));


		dgFloat64 num1 = DotProduct (size, r0, MinvR0);
		dgFloat64 beta = num1 / num;
		ScaleAdd (size, p0, MinvR0, beta, p0);
		num = DotProduct (size, r0, MinvR0);
		iter ++;
		error2 = num;
		if (j > 10) {
			error2 = dgFloat64 (0.0f);
			for (dgInt32 i = 0; i < size; i ++) {
				error2 = dgMax (error2, r0[i] * r0[i]);
			}
		}
	}

	dgAssert (iter < size);
	return num;
}
Пример #5
0
dgConvexHull4d::dgListNode* dgConvexHull4d::FindFacingNode(const dgBigVector& vertex)
{
	const dgHullVector* const hullVertexArray = &m_points[0];

	dgListNode* bestNode = GetFirst();
	dgConvexHull4dTetraherum* const tetra = &bestNode->GetInfo();
	dgConvexHull4dTetraherum::dgTetrahedrumPlane plane (tetra->GetPlaneEquation (hullVertexArray));
	dgFloat64 dist = plane.Evalue(vertex);
	dgInt32 mark = IncMark();
	tetra->SetMark(mark);

	dgInt8 buffer[1024 * 2 * sizeof (dgFloat64)];
	dgDownHeap<dgListNode*, dgFloat64> heap (buffer, sizeof (buffer));

	heap.Push(bestNode, dist);
	dgInt32 maxCount = heap.GetMaxCount() - 1;
	dgInt32 releafCount = maxCount >> 3;
	while (heap.GetCount()) {
		dgListNode* const node = heap[0];
		dgFloat64 dist = heap.Value();
		if (dist > dgFloat64 (1.0e-5f)) {
			return node;
		}
		heap.Pop();
		dgConvexHull4dTetraherum* const tetra = &node->GetInfo();
		for (dgInt32 i = 0; i < 4; i ++) {
			dgListNode* neigborghNode = tetra->m_faces[i].m_twin;
			dgConvexHull4dTetraherum* const neighborgh = &neigborghNode->GetInfo();
			if (neighborgh->GetMark() != mark) {
				neighborgh->SetMark(mark);
				if (heap.GetCount() >= maxCount) {
					for (dgInt32 i = 0; i < releafCount; i ++) {
						heap.Remove(heap.GetCount() - 1);
					}
				}
				dgConvexHull4dTetraherum::dgTetrahedrumPlane plane (neighborgh->GetPlaneEquation (hullVertexArray));
				heap.Push(neigborghNode, plane.Evalue(vertex));
			}
		}
	}

	for (dgListNode* node = GetFirst(); node; node = node->GetNext()) {
		dgConvexHull4dTetraherum* const tetra = &node->GetInfo();
		dgFloat64 dist = tetra->Evalue(hullVertexArray, vertex);
		if (dist > dgFloat64(0.0f)) {
			return node;
		}
	}


	return NULL;
}
Пример #6
0
dgBigVector dgPointToTetrahedrumDistance (const dgBigVector& point, const dgBigVector& p0, const dgBigVector& p1, const dgBigVector& p2, const dgBigVector& p3)
{
	const dgBigVector e10(p1 - p0);
	const dgBigVector e20(p2 - p0);
	const dgBigVector e30(p3 - p0);

	const dgFloat64 d0 = sqrt(e10.DotProduct(e10).GetScalar());
	if (d0 > dgFloat64(0.0f)) {
		const dgFloat64 invd0 = dgFloat64(1.0f) / d0;
		const dgFloat64 l10 = e20.DotProduct(e10).GetScalar() * invd0;
		const dgFloat64 l20 = e30.DotProduct(e10).GetScalar() * invd0;
		const dgFloat64 desc11 = e20.DotProduct(e20).GetScalar() - l10 * l10;
		if (desc11 > dgFloat64(0.0f)) {
			const dgFloat64 d1 = sqrt(desc11);
			const dgFloat64 invd1 = dgFloat64(1.0f) / d1;
			const dgFloat64 l21 = (e30.DotProduct(e20).GetScalar() - l20 * l10) * invd1;
			const dgFloat64 desc22 = e30.DotProduct(e30).GetScalar() - l20 * l20 - l21 * l21;
			if (desc22 > dgFloat64(0.0f)) {
				dgBigVector p0Point (point - p0);
				const dgFloat64 d2 = sqrt(desc22);
				const dgFloat64 invd2 = dgFloat64(1.0f) / d2;
				
				const dgFloat64 b0 = e10.DotProduct(p0Point).GetScalar();
				const dgFloat64 b1 = e20.DotProduct(p0Point).GetScalar();
				const dgFloat64 b2 = e30.DotProduct(p0Point).GetScalar();

				dgFloat64 u1 = b0 * invd0;
				dgFloat64 u2 = (b1 - l10 * u1) * invd1;
				dgFloat64 u3 = (b2 - l20 * u1 - l21 * u2) * invd2 * invd2;
				u2 = (u2 - l21 * u3) * invd1;
				u1 = (u1 - l10 * u2 - l20 * u3) * invd0;
				if (u3 < dgFloat64(0.0f)) {
					// this looks funny but it is correct
					return dgPointToTriangleDistance(point, p0, p1, p2);
				} else if (u2 < dgFloat64(0.0f)) {
					return dgPointToTriangleDistance(point, p0, p1, p3);
				} else if (u1 < dgFloat64(0.0f)) {
					return dgPointToTriangleDistance(point, p0, p2, p3);
				} else if (u1 + u2 + u3 > dgFloat64(1.0f)) {
					return dgPointToTriangleDistance(point, p1, p2, p3);
				}
				return p0 + e10.Scale(u1) + e20.Scale(u2) + e30.Scale(u3);
			}
		}
	}
	// this is a degenerated tetra. this should never happens
	dgAssert(0);
	return p0;
}
Пример #7
0
dgBigVector dgPointToTriangleDistance(const dgBigVector& point, const dgBigVector& p0, const dgBigVector& p1, const dgBigVector& p2)
{
	const dgBigVector e10(p1 - p0);
	const dgBigVector e20(p2 - p0);
	const dgFloat64 a00 = e10.DotProduct(e10).GetScalar();
	const dgFloat64 a11 = e20.DotProduct(e20).GetScalar();
	const dgFloat64 a01 = e10.DotProduct(e20).GetScalar();

	const dgFloat64 det = a00 * a11 - a01 * a01;
	dgAssert(det >= dgFloat32(0.0f));
	if (dgAbs(det) > dgFloat32(1.0e-24f)) {
		dgBigVector p0Point (point - p0);
		const dgFloat64 b0 = e10.DotProduct(p0Point).GetScalar();
		const dgFloat64 b1 = e20.DotProduct(p0Point).GetScalar();

		const dgFloat64 beta = b1 * a00 - a01 * b0;
		const dgFloat64 alpha = b0 * a11 - a01 * b1;
		if (beta < dgFloat32(0.0f)) {
			return dgPointToRayDistance (point, p0, p1);
		} else if (alpha < dgFloat32(0.0f)) {
			return dgPointToRayDistance (point, p0, p2);
		} else if ((alpha + beta) > det) {
			return dgPointToRayDistance (point, p1, p2);
		}
		return p0 + (e10.Scale(alpha) + e20.Scale(beta)).Scale(dgFloat64(1.0f) / det);
	}
	// this is a degenerated triangle. this should never happens
	dgAssert(0);
	return p0;
}
Пример #8
0
dgBigVector dgPointToRayDistance (const dgBigVector& point, const dgBigVector& ray_p0, const dgBigVector& ray_p1)
{
	dgBigVector dp (ray_p1 - ray_p0);
	dgAssert (dp.m_w == dgFloat32 (0.0f));
	dgFloat64 t = dgClamp (dp.DotProduct3 (point - ray_p0) / dp.DotProduct3 (dp), dgFloat64(0.0f), dgFloat64 (1.0f));
	return ray_p0 + dp.Scale (t);
}
	DG_INLINE void CalculateBodyDiagonal(dgSkeletonGraph* const child)
	{
		dgAssert(child->m_joint);
		
		dgSpatialMatrix copy;
		copy.SetZero();
		const dgInt32 dof = child->m_dof;
		const dgSpatialMatrix& jacobianMatrix = child->m_jointJ;
		const dgSpatialMatrix& childDiagonal = child->m_jointMass;
		for (dgInt32 i = 0; i < dof ; i++) {
			const dgSpatialVector& jacobian = jacobianMatrix[i];
			for (dgInt32 j = 0; j < dof ; j++) {
				dgAssert(dgAreEqual (childDiagonal[i][j], childDiagonal[j][i], dgFloat64(1.0e-5f)));
				dgFloat64 val = childDiagonal[i][j];
				jacobian.ScaleAdd(val, copy[j], copy[j]);
			}
		}

		for (dgInt32 i = 0; i < dof; i++) {
			const dgSpatialVector& Jacobian = copy[i];
			const dgSpatialVector& JacobianTranspose = jacobianMatrix[i];
			for (dgInt32 j = 0; j < 6; j++) {
				dgFloat64 val = -Jacobian[j];
				JacobianTranspose.ScaleAdd(val, m_bodyMass[j], m_bodyMass[j]);
			}
		}
	}
Пример #10
0
dgFloat64 dgSymmetricBiconjugateGradientSolve::DotProduct (dgInt32 size, const dgFloat64 * const b, const dgFloat64 * const c) const
{
   dgFloat64 product = dgFloat64 (0.0f);
   for (dgInt32 i = 0; i < size; i ++)
      product += b[i] * c[i];
   return product;
}
void dgDelaunayTetrahedralization::RemoveUpperHull()
{
#ifdef _WIN32
  dgUnsigned32 controlWorld = dgControlFP (0xffffffff, 0);
  dgControlFP(_PC_53, _MCW_PC);
#endif

  dgListNode* nextNode = NULL;
//	const dgHullVector* const points = &m_points[0];
  for (dgListNode* node = GetFirst(); node; node = nextNode)
  {
    nextNode = node->GetNext();

    dgConvexHull4dTetraherum* const tetra = &node->GetInfo();
    tetra->SetMark(0);

//		const dgBigVector &p0 = points[tetra->m_faces[0].m_index[0]];
//		const dgBigVector &p1 = points[tetra->m_faces[0].m_index[1]];
//		const dgBigVector &p2 = points[tetra->m_faces[0].m_index[2]];
//		const dgBigVector &p3 = points[tetra->m_faces[0].m_otherVertex];
//		dgFloat64 w = GetTetraVolume (p0, p1, p2, p3);
    dgFloat64 w = GetTetraVolume(tetra);
    if (w >= dgFloat64(0.0f))
    {
      DeleteFace(node);
    }
  }

#ifdef _WIN32
  dgControlFP(controlWorld, _MCW_PC);
#endif
}
Пример #12
0
	static void Statistics (dgObb& sphere, dgVector &eigenValues, dgVector &scaleVector, const dgFloat32 vertex[], dgInt32 vertexCount, dgInt32 stride)
	{
		dgBigVector var (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
		dgBigVector cov (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
		dgBigVector massCenter (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
	
		const dgFloat32* ptr = vertex;
		for (dgInt32 i = 0; i < vertexCount; i ++) {
			dgFloat32 x = ptr[0] * scaleVector.m_x;
			dgFloat32 y = ptr[1] * scaleVector.m_y;
			dgFloat32 z = ptr[2] * scaleVector.m_z;
			ptr += stride;
			massCenter += dgBigVector (x, y, z, dgFloat32 (0.0f));
			var += dgBigVector (x * x, y * y, z * z, dgFloat32 (0.0f));
			cov += dgBigVector (x * y, x * z, y * z, dgFloat32 (0.0f));
		}
	
		dgFloat64 k = dgFloat64 (1.0) / vertexCount;
		var = var.Scale3 (k);
		cov = cov.Scale3 (k);
		massCenter = massCenter.Scale3 (k);
	
		dgFloat64 Ixx = var.m_x - massCenter.m_x * massCenter.m_x;
		dgFloat64 Iyy = var.m_y - massCenter.m_y * massCenter.m_y;
		dgFloat64 Izz = var.m_z - massCenter.m_z * massCenter.m_z;
	
		dgFloat64 Ixy = cov.m_x - massCenter.m_x * massCenter.m_y;
		dgFloat64 Ixz = cov.m_y - massCenter.m_x * massCenter.m_z;
		dgFloat64 Iyz = cov.m_z - massCenter.m_y * massCenter.m_z;
	
		sphere.m_front = dgVector (dgFloat32(Ixx), dgFloat32(Ixy), dgFloat32(Ixz), dgFloat32 (0.0f));
		sphere.m_up    = dgVector (dgFloat32(Ixy), dgFloat32(Iyy), dgFloat32(Iyz), dgFloat32 (0.0f));
		sphere.m_right = dgVector (dgFloat32(Ixz), dgFloat32(Iyz), dgFloat32(Izz), dgFloat32 (0.0f));
 		sphere.EigenVectors (eigenValues);
	}
Пример #13
0
dgFloat32 dgRayCastSphere (const dgVector& p0, const dgVector& p1, const dgVector& origin, dgFloat32 radius)
{
	dgVector p0Origin (p0 - origin);
	if (p0Origin.DotProduct3(p0Origin) < (dgFloat32 (100.0f) * radius * radius)) {
		dgVector dp (p1 - p0);
		dgFloat32 a = dp.DotProduct3(dp);
		dgFloat32 b = dgFloat32 (2.0f) * p0Origin.DotProduct3(dp);
		dgFloat32 c = p0Origin.DotProduct3(p0Origin) - radius * radius;
		dgFloat32 desc = b * b - dgFloat32 (4.0f) * a * c;
		if (desc >= 0.0f) {
			desc = dgSqrt (desc);
			dgFloat32 den = dgFloat32 (0.5f) / a;
			dgFloat32 t0 = (-b + desc) * den;
			dgFloat32 t1 = (-b - desc) * den;
			if ((t0 >= dgFloat32 (0.0f)) && (t1 >= dgFloat32 (0.0f))) {
				t0 =  dgMin(t0, t1);
				if (t0 <= dgFloat32 (1.0f)) {
					return t0;
				}
			} else if (t0 >= dgFloat32 (0.0f)) {
				if (t0 <= dgFloat32 (1.0f)) {
					return t0;
				}
			} else {
				if ((t1 >= dgFloat32 (0.0f)) && (t1 <= dgFloat32 (1.0f))) {
					return t1;
				}
			}
		}
	} else {
		dgBigVector p0Origin1 (p0Origin);
		dgBigVector dp (p1 - p0);
		dgFloat64 a = dp.DotProduct3(dp);
		dgFloat64 b = dgFloat32 (2.0f) * p0Origin1.DotProduct3(dp);
		dgFloat64 c = p0Origin1.DotProduct3(p0Origin1) - dgFloat64(radius) * radius;
		dgFloat64 desc = b * b - dgFloat32 (4.0f) * a * c;
		if (desc >= 0.0f) {
			desc = sqrt (desc);
			dgFloat64 den = dgFloat32 (0.5f) / a;
			dgFloat64 t0 = (-b + desc) * den;
			dgFloat64 t1 = (-b - desc) * den;
			if ((t0 >= dgFloat32 (0.0f)) && (t1 >= dgFloat32 (0.0f))) {
				t0 =  dgMin(t0, t1);
				if (t0 <= dgFloat32 (1.0f)) {
					return dgFloat32 (t0);
				}
			} else if (t0 >= dgFloat32 (0.0f)) {
				if (t0 <= dgFloat32 (1.0f)) {
					return dgFloat32 (t0);
				}
			} else {
				if ((t1 >= dgFloat32 (0.0f)) && (t1 <= dgFloat32 (1.0f))) {
					return dgFloat32 (t1);
				}
			}
		}
	}
	return dgFloat32 (1.2f);
}
//dgFloat64 dgDelaunayTetrahedralization::GetTetraVolume (const dgBigVector& p0, const dgBigVector& p1, const dgBigVector& p2, const dgBigVector& p3) const
dgFloat64 dgDelaunayTetrahedralization::GetTetraVolume(
    const dgConvexHull4dTetraherum* const tetra) const
{
  //	dgBigVector p1p0 (p1.Sub4(p0));
  //	dgBigVector p2p0 (p2.Sub4(p0));
  //	dgBigVector p3p0 (p3.Sub4(p0));
  //	dgBigVector normal (p1p0.CrossProduct4 (p2p0, p3p0));
  //  dgFloat64 det = normal.m_w;

  const dgHullVector* const points = &m_points[0];
  const dgBigVector &p0 = points[tetra->m_faces[0].m_index[0]];
  const dgBigVector &p1 = points[tetra->m_faces[0].m_index[1]];
  const dgBigVector &p2 = points[tetra->m_faces[0].m_index[2]];
  const dgBigVector &p3 = points[tetra->m_faces[0].m_otherVertex];

  dgFloat64 matrix[3][3];
  for (dgInt32 i = 0; i < 3; i++)
  {
    matrix[0][i] = p2[i] - p0[i];
    matrix[1][i] = p1[i] - p0[i];
    matrix[2][i] = p3[i] - p0[i];
  }

  dgFloat64 error;
  dgFloat64 det = Determinant3x3(matrix, &error);

  dgFloat64 precision = dgFloat64(1.0f) / dgFloat64(1 << 24);
  dgFloat64 errbound = error * precision;
  if (fabs(det) > errbound)
  {
    return det;
  }

  dgGoogol exactMatrix[3][3];
  for (dgInt32 i = 0; i < 3; i++)
  {
    exactMatrix[0][i] = dgGoogol(p2[i]) - dgGoogol(p0[i]);
    exactMatrix[1][i] = dgGoogol(p1[i]) - dgGoogol(p0[i]);
    exactMatrix[2][i] = dgGoogol(p3[i]) - dgGoogol(p0[i]);
  }

  dgGoogol exactDet(Determinant3x3(exactMatrix));
  det = exactDet.GetAproximateValue();
  return det;
}
bool dgCollisionConvexHull::CheckConvex (dgPolyhedra& polyhedra1, const dgBigVector* hullVertexArray) const
{
	dgPolyhedra polyhedra(polyhedra1);

	dgPolyhedra::Iterator iter (polyhedra);
	dgBigVector center (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));

	dgInt32 count = 0;
	dgInt32 mark = polyhedra.IncLRU();
	for (iter.Begin(); iter; iter ++) {
		dgEdge* const edge = &(*iter);
		if (edge->m_mark < mark) {
			count ++;
			center += hullVertexArray[edge->m_incidentVertex];
			dgEdge* ptr = edge;
			do {
				ptr->m_mark = mark;
				ptr = ptr->m_twin->m_next;
			} while (ptr != edge);
		}
	}
	center = center.Scale3 (dgFloat64 (1.0f) / dgFloat64 (count));

	for (iter.Begin(); iter; iter ++) {
		dgEdge* const edge = &(*iter);
		dgBigVector normal0 (FaceNormal (edge, hullVertexArray));
		dgBigVector normal1 (FaceNormal (edge->m_twin, hullVertexArray));

		dgBigPlane plane0 (normal0, - (normal0 % hullVertexArray[edge->m_incidentVertex]));
		dgBigPlane plane1 (normal1, - (normal1 % hullVertexArray[edge->m_twin->m_incidentVertex]));
		dgFloat64 test0 = plane0.Evalue(center);
		if (test0 > dgFloat64 (1.0e-3f)) {
			return false;
		}
		dgFloat64 test1 = plane1.Evalue(center);
//		if (test1 > dgFloat64 (0.0f)) {
		if (test1 > dgFloat64 (1.0e-3f)) {
			return false;
		}
	}

	return true;
}
dgBigVector LineTriangleIntersection (const dgBigVector& p0, const dgBigVector& p1, const dgBigVector& A, const dgBigVector& B, const dgBigVector& C)
{
	dgHugeVector ph0 (p0);
	dgHugeVector ph1 (p1);
	dgHugeVector Ah (A);
	dgHugeVector Bh (B);
	dgHugeVector Ch (C);

	dgHugeVector p1p0 (ph1 - ph0);
	dgHugeVector Ap0 (Ah - ph0);
	dgHugeVector Bp0 (Bh - ph0);
	dgHugeVector Cp0 (Ch - ph0);

	dgGoogol t0 ((Bp0 * Cp0) % p1p0);
	dgFloat64 val0 = t0.GetAproximateValue();	
	if (val0 < dgFloat64 (0.0f)) {
		return dgBigVector (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (-1.0f));
	}

	dgGoogol t1 ((Cp0 * Ap0) % p1p0);
	dgFloat64 val1 = t1.GetAproximateValue();	
	if (val1 < dgFloat64 (0.0f)) {
		return dgBigVector (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (-1.0f));
	}

	dgGoogol t2 ((Ap0 * Bp0) % p1p0);
	dgFloat64 val2 = t2.GetAproximateValue();	
	if (val2 < dgFloat64 (0.0f)) {
		return dgBigVector (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (-1.0f));
	}

	dgGoogol sum = t0 + t1 + t2;
	dgFloat64 den = sum.GetAproximateValue();

#ifdef _DEBUG
	dgBigVector testpoint (A.Scale (val0 / den) + B.Scale (val1 / den) + C.Scale(val2 / den));
	dgFloat64 volume = ((B - A) * (C - A)) % (testpoint - A);
	_ASSERTE (fabs (volume) < dgFloat64 (1.0e-12f));
#endif


	return dgBigVector (val0 / den, val1 / den, val2 / den, dgFloat32 (0.0f));
}
Пример #17
0
dgFloat64 dgConvexHull4d::RoundToFloat (dgFloat64 val) const
{
	dgInt32 exp;
	dgFloat64 mantissa = frexp(val, &exp);

	const dgFloat64 power = 1<<23;
	const dgFloat64 invPower = dgFloat64 (1.0f) / power;
	mantissa = floor(mantissa * power) * invPower;

	dgFloat64 val1 = ldexp (mantissa, exp);
	return val1;
}
dgBigVector dgCollisionConvexHull::FaceNormal (const dgEdge *face, const dgBigVector* const pool) const
{
	const dgEdge* edge = face;
	dgBigVector p0 (pool[edge->m_incidentVertex]);
	edge = edge->m_next;

	dgBigVector p1 (pool[edge->m_incidentVertex]);
	dgBigVector e1 (p1 - p0);

	dgBigVector normal (dgFloat32 (0.0f));
	for (edge = edge->m_next; edge != face; edge = edge->m_next) {
		dgBigVector p2 (pool[edge->m_incidentVertex]);
		dgBigVector e2 (p2 - p0);
		dgBigVector n1 (e1.CrossProduct(e2));
#ifdef _DEBUG
		dgAssert(n1.m_w == dgFloat32(0.0f));
		dgFloat64 mag = normal.DotProduct(n1).GetScalar();
		dgAssert ( mag >= -dgFloat32 (0.1f));
#endif
		normal += n1;
		e1 = e2;
	} 

	dgFloat64 den = sqrt (normal.DotProduct(normal).GetScalar()) + dgFloat64 (1.0e-24f);
	normal = normal.Scale (dgFloat64 (1.0f)/ den);

#ifdef _DEBUG
	edge = face;
	dgBigVector e0 (pool[edge->m_incidentVertex] - pool[edge->m_prev->m_incidentVertex]);	
	do {
		dgBigVector de1 (pool[edge->m_next->m_incidentVertex] - pool[edge->m_incidentVertex]);	
		dgBigVector dn1 (e0.CrossProduct(de1));
		dgFloat64 x = normal.DotProduct(dn1).GetScalar();
		dgAssert (x > -dgFloat64 (0.01f));
		e0 = de1;
		edge = edge->m_next;
	} while (edge != face);
#endif
	return normal;
}
Пример #19
0
dgBigVector dgCollisionConvexHull::FaceNormal (const dgEdge *face, const dgBigVector* const pool) const
{
	const dgEdge *edge = face;
	dgBigVector p0 (pool[edge->m_incidentVertex]);
	edge = edge->m_next;

	dgBigVector p1 (pool[edge->m_incidentVertex]);
	dgBigVector e1 (p1 - p0);

	dgBigVector normal (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
	for (edge = edge->m_next; edge != face; edge = edge->m_next) {
		dgBigVector p2 (pool[edge->m_incidentVertex]);
		dgBigVector e2 (p2 - p0);
		dgBigVector n1 (e1 * e2);
#ifdef _DEBUG
		dgFloat64 mag = normal % n1;
		_ASSERTE ( mag >= -dgFloat32 (0.1f));
#endif
		normal += n1;
		e1 = e2;
	} 
	dgFloat64 den = sqrt (normal % normal) + dgFloat64 (1.0e-24f);
	normal = normal.Scale (dgFloat64 (1.0f)/ den);

#ifdef _DEBUG
	edge = face;
	dgBigVector e0 (pool[edge->m_incidentVertex] - pool[edge->m_prev->m_incidentVertex]);	
	do {
		dgBigVector e1 (pool[edge->m_next->m_incidentVertex] - pool[edge->m_incidentVertex]);	
		dgBigVector n1 (e0 * e1);
		dgFloat64 x = normal % n1;
		_ASSERTE (x > -dgFloat64 (0.01f));
		e0 = e1;
		edge = edge->m_next;
	} while (edge != face);
#endif

	return normal;
}
Пример #20
0
dgConvexHull4dTetraherum::dgTetrahedrumPlane::dgTetrahedrumPlane (const dgBigVector& p0, const dgBigVector& p1, const dgBigVector& p2, const dgBigVector& p3)
	:dgBigVector ((p1 - p0).CrossProduct4 (p2 - p0, p3 - p0))
{
	dgBigVector& me = *this;
//	dgAssert (me.DotProduct4(me) > dgFloat64 (1.0e-64f));
	dgFloat64 invMag2 = dgFloat32 (0.0f);
//	if (me.DotProduct4(me) > dgFloat64 (1.0e-64)) {
//	if (me.DotProduct4(me) > dgFloat64 (1.0e-38)) {
	dgFloat64 val = me.DotProduct4(me).m_x;
	if (val > dgFloat64 (1.0e-38)) {
		//invMag2 = dgFloat64 (1.0f) / sqrt (me.DotProduct4(me));
		invMag2 = dgFloat64 (1.0f) / sqrt (val);
	} else {
		invMag2 = dgFloat32 (0.0f);
	}

	me.m_x *= invMag2;
	me.m_y *= invMag2;
	me.m_z *= invMag2;
	me.m_w *= invMag2;
	m_dist = - me.DotProduct4(p0).m_x;
}
Пример #21
0
dgGoogol Determinant4x4 (const dgGoogol matrix[4][4])
{
	dgGoogol sign = dgFloat64 (1.0f);
	dgGoogol det = dgFloat64 (0.0f);
	dgGoogol negOne (dgFloat64 (-1.0f));
	dgGoogol accError = dgFloat64 (0.0f); 
	for (dgInt32 i = 0; i < 4; i ++)  {
		dgGoogol  cofactor[3][3];
		for (dgInt32 j = 0; j < 3; j ++) {
			dgInt32 k0 = 0;
			for (dgInt32 k = 0; k < 4; k ++) {
				if (k != i) {
					cofactor[j][k0] = matrix[j][k];
					k0 ++;
				}
			}
		}

		dgGoogol minorDet = Determinant3x3 (cofactor);
		det = det + sign * minorDet * matrix[3][i];
		sign = sign * negOne;
	}
	return det;
}
Пример #22
0
dgGoogol Determinant3x3 (const dgGoogol matrix[3][3])
{
	dgGoogol negOne (dgFloat64 (-1.0f));
	dgGoogol sign (dgFloat64 (-1.0f));
	dgGoogol det = dgFloat64 (0.0f);
	for (dgInt32 i = 0; i < 3; i ++)  {
		dgGoogol cofactor[2][2];

		for (dgInt32 j = 0; j < 2; j ++) {
			dgInt32 k0 = 0;
			for (dgInt32 k = 0; k < 3; k ++) {
				if (k != i) {
					cofactor[j][k0] = matrix[j][k];
					k0 ++;
				}
			}
		}

		dgGoogol minorDet (Determinant2x2 (cofactor));
		det = det + sign * minorDet * matrix[2][i];
		sign = sign * negOne;
	}
	return det;
}
Пример #23
0
	dgGoogol::dgGoogol(dgFloat64 value)
		:m_sign(0)
		,m_exponent(0)
	{
		dgInt32 exp;
		dgFloat64 mantissa = fabs (frexp(value, &exp));

		m_exponent = dgInt16 (exp);
		m_sign = (value >= 0) ? 0 : 1;

		memset (m_mantissa, 0, sizeof (m_mantissa));
		m_mantissa[0] = (dgInt64 (dgFloat64 (dgUnsigned64(1)<<62) * mantissa));

		// it looks like GCC have problems with this
		//dgAssert (m_mantissa[0] >= 0);
		dgAssert ((m_mantissa[0] & dgUnsigned64(1)<<63) == 0);
	}
Пример #24
0
void dgConvexHull4dTetraherum::Init (const dgHullVector* const points, dgInt32 v0, dgInt32 v1, dgInt32 v2, dgInt32 v3)
{
	//{0, 1, 2, 3}, 
	//{3, 0, 2, 1}, 
	//{3, 2, 1, 0}, 
	//{3, 1, 0, 2}

	m_faces[0].m_index[0] = v0;
	m_faces[0].m_index[1] = v1;
	m_faces[0].m_index[2] = v2;
	m_faces[0].m_index[3] = v3;

	m_faces[1].m_index[0] = v3;
	m_faces[1].m_index[1] = v0;
	m_faces[1].m_index[2] = v2;
	m_faces[1].m_index[3] = v1;

	m_faces[2].m_index[0] = v3;
	m_faces[2].m_index[1] = v2;
	m_faces[2].m_index[2] = v1;
	m_faces[2].m_index[3] = v0;

	m_faces[3].m_index[0] = v3;
	m_faces[3].m_index[1] = v1;
	m_faces[3].m_index[2] = v0;
	m_faces[3].m_index[3] = v2;

	SetMark (0); 
	for (dgInt32 i = 0; i < 4; i ++) {
		m_faces[i].m_twin = NULL;
	}

#ifdef _DEBUG
	dgBigVector p1p0 (points[v1] - points[v0]);
	dgBigVector p2p0 (points[v2] - points[v0]);
	dgBigVector p3p0 (points[v3] - points[v0]);
	dgBigVector normal (p1p0.CrossProduct4(p2p0, p3p0));
	dgFloat64 volume = normal.DotProduct4(normal).m_x;
	dgAssert (volume > dgFloat64 (0.0f));
#endif
}
Пример #25
0
void dgPolygonSoupDatabaseBuilder::End(bool optimize)
{
  Optimize(optimize);

  // build the normal array and adjacency array
  // calculate all face the normals
  dgInt32 indexCount = 0;
  m_normalPoints[m_faceCount].m_x = dgFloat64(0.0f);
  for (dgInt32 i = 0; i < m_faceCount; i++)
  {
    dgInt32 faceIndexCount = m_faceVertexCount[i];

    dgInt32* const ptr = &m_vertexIndex[indexCount + 1];
    dgBigVector v0(&m_vertexPoints[ptr[0]].m_x);
    dgBigVector v1(&m_vertexPoints[ptr[1]].m_x);
    dgBigVector e0(v1 - v0);
    dgBigVector normal(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f),
        dgFloat32(0.0f));
    for (dgInt32 j = 2; j < faceIndexCount - 1; j++)
    {
      dgBigVector v2(&m_vertexPoints[ptr[j]].m_x);
      dgBigVector e1(v2 - v0);
      normal += e0 * e1;
      e0 = e1;
    }
    normal = normal.Scale(dgRsqrt (normal % normal));

    m_normalPoints[i].m_x = normal.m_x;
    m_normalPoints[i].m_y = normal.m_y;
    m_normalPoints[i].m_z = normal.m_z;
    indexCount += faceIndexCount;
  }
  // compress normals array
  m_normalIndex[m_faceCount] = 0;
  m_normalCount = dgVertexListToIndexList(&m_normalPoints[0].m_x,
      sizeof(dgBigVector), 3, m_faceCount, &m_normalIndex[0],
      dgFloat32(1.0e-4f));
}
Пример #26
0
dgFloat32 dgFastRayTest::PolygonIntersect (const dgVector& faceNormal, dgFloat32 maxT, const dgFloat32* const polygon, dgInt32 strideInBytes, const dgInt32* const indexArray, dgInt32 indexCount) const
{
	dgAssert (m_p0.m_w == dgFloat32 (0.0f));
	dgAssert (m_p1.m_w == dgFloat32 (0.0f));

	if (faceNormal.DotProduct(m_unitDir).GetScalar() < dgFloat32 (0.0f)) {
		dgInt32 stride = dgInt32(strideInBytes / sizeof (dgFloat32));
		dgBigVector v0(dgVector(&polygon[indexArray[indexCount - 1] * stride]) & dgVector::m_triplexMask);
		dgBigVector p0(m_p0);
		dgBigVector p0v0(v0 - p0);

		dgBigVector diff(m_diff);
		dgBigVector normal(faceNormal);
		dgFloat64 tOut = normal.DotProduct(p0v0).GetScalar() / normal.DotProduct(diff).GetScalar();
		if ((tOut >= dgFloat64(0.0f)) && (tOut <= maxT)) {
			dgBigVector p (p0 + diff.Scale (tOut));
			dgBigVector unitDir(m_unitDir);
			for (dgInt32 i = 0; i < indexCount; i++) {
				dgInt32 i2 = indexArray[i] * stride;
				dgBigVector v1(dgVector(&polygon[i2]) & dgVector::m_triplexMask);

				dgBigVector edge0(p - v0);
				dgBigVector edge1(v1 - v0);
				dgFloat64 area = unitDir.DotProduct (edge0.CrossProduct(edge1)).GetScalar();
				if (area < dgFloat32 (0.0f)) {
					return 1.2f;
				}
				v0 = v1;
			}

			return dgFloat32(tOut);
		}
	}

	return dgFloat32 (1.2f);
}
Пример #27
0
dgBigVector dgConvexHull4dTetraherum::CircumSphereCenter (const dgHullVector* const pointArray) const
{
	dgGoogol matrix[4][4];

	dgBigVector points[4];
	points[0] = pointArray[m_faces[0].m_index[0]];
	points[1] = pointArray[m_faces[0].m_index[1]];
	points[2] = pointArray[m_faces[0].m_index[2]];
	points[3] = pointArray[m_faces[0].m_index[3]];

	for (dgInt32 i = 0; i < 4; i ++) {
		for (dgInt32 j = 0; j < 3; j ++) {
			matrix[i][j] = dgGoogol (points[i][j]);
		}
		matrix[i][3] = dgGoogol (1.0f);
	}
	dgGoogol det (Determinant4x4(matrix));
	dgFloat64 invDen = dgFloat64 (1.0f) / (dgFloat64(det) * dgFloat64 (2.0f));

	dgBigVector centerOut;
	dgFloat64 sign = dgFloat64 (1.0f);
	for (dgInt32 k = 0; k < 3; k ++) {
		for (dgInt32 i = 0; i < 4; i ++) {
			matrix[i][0] = dgGoogol (points[i][3]);
			for (dgInt32 j = 0; j < 2; j ++) {
				dgInt32 j1 = (j < k) ? j : j + 1; 
				matrix[i][j + 1] = dgGoogol (points[i][j1]);
			}
			matrix[i][3] = dgGoogol (1.0f);
		}
		dgGoogol det (Determinant4x4(matrix));
		dgFloat64 val = dgFloat64 (det) * sign;
		sign *= dgFloat64 (-1.0f);
		centerOut[k] = val * invDen; 
	}
	centerOut[3] = dgFloat32 (0.0f);
	return centerOut;
}
Пример #28
0
void dgConvexHull4d::InsertNewVertex(dgInt32 vertexIndex, dgListNode* const frontFace, dgList<dgListNode*>& deletedFaces, dgList<dgListNode*>& newFaces)
{
	dgAssert (Sanity());
	dgList<dgListNode*> stack(GetAllocator());
	
	dgInt32 mark = IncMark();
	stack.Append(frontFace);
	dgHullVector* const hullVertexArray = &m_points[0];
	const dgBigVector& p = hullVertexArray[vertexIndex];
	while (stack.GetCount()) {
		dgList<dgListNode*>::dgListNode* const stackNode = stack.GetLast();
		dgListNode* const node = stackNode->GetInfo();
		stack.Remove(stackNode);
		dgConvexHull4dTetraherum* const face = &node->GetInfo();
		if ((face->GetMark() != mark) && (face->Evalue(hullVertexArray, p) > dgFloat64(0.0f))) { 
#ifdef _DEBUG
			for (dgList<dgListNode*>::dgListNode* deleteNode = deletedFaces.GetFirst(); deleteNode; deleteNode = deleteNode->GetNext()) {
				dgAssert (deleteNode->GetInfo() != node);
			}
#endif
			deletedFaces.Append(node);

			face->SetMark(mark);
			for (dgInt32 i = 0; i < 4; i ++) {
				dgListNode* const twinNode = (dgListNode*)face->m_faces[i].m_twin;
				dgAssert (twinNode);
				dgConvexHull4dTetraherum* const twinFace = &twinNode->GetInfo();

				if (twinFace->GetMark() != mark) {
					stack.Append(twinNode);
				}
			}
		}
	}

    dgTree<dgListNode*, dgInt32> perimeter(GetAllocator());
	for (dgList<dgListNode*>::dgListNode* deleteNode = deletedFaces.GetFirst(); deleteNode; deleteNode = deleteNode->GetNext()) {
		dgListNode* const deleteTetraNode = deleteNode->GetInfo();
		dgConvexHull4dTetraherum* const deletedTetra = &deleteTetraNode->GetInfo();
		dgAssert (deletedTetra->GetMark() == mark);
		for (dgInt32 i = 0; i < 4; i ++) {
			dgListNode* const twinNode = deletedTetra->m_faces[i].m_twin;
			dgConvexHull4dTetraherum* const twinTetra = &twinNode->GetInfo();

			if (twinTetra->GetMark() != mark) {
				if (!perimeter.Find(twinTetra->m_uniqueID)) {
					perimeter.Insert(twinNode, twinTetra->m_uniqueID);
				}
			}
			deletedTetra->m_faces[i].m_twin = NULL;
		}
	}

	dgList<dgListNode*> coneList(GetAllocator());
	dgTree<dgListNode*, dgInt32>::Iterator iter (perimeter);
	for (iter.Begin(); iter; iter ++) {
		dgListNode* const perimeterNode = iter.GetNode()->GetInfo();
		dgConvexHull4dTetraherum* const perimeterTetra = &perimeterNode->GetInfo();
		for (dgInt32 i = 0; i < 4; i ++) {
			dgConvexHull4dTetraherum::dgTetrahedrumFace* const perimeterFace = &perimeterTetra->m_faces[i];

			if (perimeterFace->m_twin->GetInfo().GetMark() == mark) {
				dgListNode* const newNode = AddFace (vertexIndex, perimeterFace->m_index[0], perimeterFace->m_index[1], perimeterFace->m_index[2]);
				newFaces.Addtop(newNode);

				dgConvexHull4dTetraherum* const newTetra = &newNode->GetInfo();
				newTetra->m_faces[2].m_twin = perimeterNode;
				perimeterFace->m_twin = newNode;
				coneList.Append (newNode);
			}
		}
	}

	for (dgList<dgListNode*>::dgListNode* coneNode = coneList.GetFirst(); coneNode->GetNext(); coneNode = coneNode->GetNext()) {
		dgListNode* const coneNodeA = coneNode->GetInfo();
		for (dgList<dgListNode*>::dgListNode* nextConeNode = coneNode->GetNext(); nextConeNode; nextConeNode = nextConeNode->GetNext()) {
			dgListNode* const coneNodeB = nextConeNode->GetInfo();
			LinkSibling (coneNodeA, coneNodeB);
		}
	}
}
Пример #29
0
dgInt32 dgConvexHull4d::InitVertexArray(dgHullVector* const points, const dgBigVector* const vertexCloud, dgInt32 count, void* const memoryPool, dgInt32 maxMemSize)
{
	for (dgInt32 i = 0; i < count; i ++) {
		points[i] = vertexCloud[i];
		points[i].m_index = i;
		points[i].m_mark = 0;
	}

	dgSort(points, count, ConvexCompareVertex);
	dgInt32 indexCount = 0;
	for (int i = 1; i < count; i ++) {
		for (; i < count; i ++) {
			if (ConvexCompareVertex (&points[indexCount], &points[i], NULL)) {
				indexCount ++;
				points[indexCount] = points[i];
				break;
			}
		}
	}
	count = indexCount + 1;
	if (count < 4) {
		m_count = 0;
		return count;
	}

	dgAABBPointTree4d* tree = BuildTree (NULL, points, count, 0, (dgInt8**) &memoryPool, maxMemSize);

	dgBigVector boxSize (tree->m_box[1] - tree->m_box[0]);	
	boxSize.m_w = dgFloat64 (0.0f);
	m_diag = dgFloat32 (sqrt (boxSize.DotProduct4(boxSize).m_x));

	m_points[4].m_x = dgFloat64 (0.0f);
	dgHullVector* const convexPoints = &m_points[0]; 
	dgStack<dgBigVector> normalArrayPool (256);
	dgBigVector* const normalArray = &normalArrayPool[0];
	dgInt32 normalCount = BuildNormalList (&normalArray[0]);

	dgInt32 index = SupportVertex (&tree, points, normalArray[0]);
	convexPoints[0] = points[index];
	points[index].m_mark = 1;

	bool validTetrahedrum = false;
	dgBigVector e1 (dgFloat64 (0.0f), dgFloat64 (0.0f), dgFloat64 (0.0f), dgFloat64 (0.0f)) ;
	for (dgInt32 i = 1; i < normalCount; i ++) {
		dgInt32 index = SupportVertex (&tree, points, normalArray[i]);
		dgAssert (index >= 0);
		e1 = points[index] - convexPoints[0];
		e1.m_w = dgFloat64 (0.0f);
		dgFloat64 error2 = e1.DotProduct4(e1).m_x;
		if (error2 > (dgFloat32 (1.0e-4f) * m_diag * m_diag)) {
			convexPoints[1] = points[index];
			points[index].m_mark = 1;
			validTetrahedrum = true;
			break;
		}
	}
	if (!validTetrahedrum) {
		m_count = 0;
		return count;
	}


	dgInt32 bestIndex = -1;
	dgFloat64 bestValue = dgFloat64 (1.0f);
	validTetrahedrum = false;
	dgFloat64 lenght2 = e1.DotProduct4(e1).m_x;
	dgBigVector e2(dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));;
	for (dgInt32 i = 2; i < normalCount; i ++) {
		dgInt32 index = SupportVertex (&tree, points, normalArray[i]);
		dgAssert (index >= 0);
		dgAssert (index < count);
		e2 = points[index] - convexPoints[0];
		e2.m_w = dgFloat64 (0.0f);
		dgFloat64 den = e2.DotProduct4(e2).m_x;
		if (fabs (den) > (dgFloat64 (1.0e-6f) * m_diag)) {
			den = sqrt (lenght2 * den);
			dgFloat64 num = e2.DotProduct4(e1).m_x;
			dgFloat64 cosAngle = fabs (num / den);
			if (cosAngle < bestValue) {
				bestValue = cosAngle;
				bestIndex = index;
			}

			if (cosAngle < 0.9f) {
				break;
			}
		}
	}

	if (bestValue < dgFloat64 (0.999f)) {
		convexPoints[2] = points[bestIndex];
		points[bestIndex].m_mark = 1;
		validTetrahedrum = true;
	}

	if (!validTetrahedrum) {
		m_count = 0;
		return count;
	}

	validTetrahedrum = false;
	dgBigVector e3(dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));;
	for (dgInt32 i = 3; i < normalCount; i ++) {
		dgInt32 index = SupportVertex (&tree, points, normalArray[i]);
		dgAssert (index >= 0);
		dgAssert (index < count);

		e3 = points[index] - convexPoints[0];
		e3.m_w = dgFloat64 (0.0f);
		dgFloat64 volume = (e1 * e2) % e3;		
		if (fabs (volume) > (dgFloat64 (1.0e-4f) * m_diag * m_diag * m_diag)) {
			convexPoints[3] = points[index];
			points[index].m_mark = 1;
			validTetrahedrum = true;
			break;
		}
	}

	m_count = 4;
	if (!validTetrahedrum) {
		m_count = 0;
	}
	
	return count;
}
Пример #30
0
dgAABBPointTree4d* dgConvexHull4d::BuildTree (dgAABBPointTree4d* const parent, dgHullVector* const points, dgInt32 count, dgInt32 baseIndex, dgInt8** memoryPool, dgInt32& maxMemSize) const
{
	dgAABBPointTree4d* tree = NULL;

	dgAssert (count);
	dgBigVector minP ( dgFloat32 (1.0e15f),  dgFloat32 (1.0e15f),  dgFloat32 (1.0e15f),  dgFloat32 (1.0e15f)); 
	dgBigVector maxP (-dgFloat32 (1.0e15f), -dgFloat32 (1.0e15f), -dgFloat32 (1.0e15f), -dgFloat32 (1.0e15f)); 
	if (count <= DG_VERTEX_CLUMP_SIZE_4D) {

		dgAABBPointTree4dClump* const clump = new (*memoryPool) dgAABBPointTree4dClump;
		*memoryPool += sizeof (dgAABBPointTree4dClump);
		maxMemSize -= sizeof (dgAABBPointTree4dClump);
		dgAssert (maxMemSize >= 0);

		dgAssert (clump);
		clump->m_count = count;
		for (dgInt32 i = 0; i < count; i ++) {
			clump->m_indices[i] = i + baseIndex;

			const dgBigVector& p = points[i];
			minP.m_x = dgMin (p.m_x, minP.m_x); 
			minP.m_y = dgMin (p.m_y, minP.m_y); 
			minP.m_z = dgMin (p.m_z, minP.m_z); 
			minP.m_w = dgMin (p.m_w, minP.m_w); 

			maxP.m_x = dgMax (p.m_x, maxP.m_x); 
			maxP.m_y = dgMax (p.m_y, maxP.m_y); 
			maxP.m_z = dgMax (p.m_z, maxP.m_z); 
			maxP.m_w = dgMax (p.m_w, maxP.m_w); 
		}

		clump->m_left = NULL;
		clump->m_right = NULL;
		tree = clump;

	} else {
		dgBigVector median (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
		dgBigVector varian (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
		for (dgInt32 i = 0; i < count; i ++) {

			const dgBigVector& p = points[i];
			minP.m_x = dgMin (p.m_x, minP.m_x); 
			minP.m_y = dgMin (p.m_y, minP.m_y); 
			minP.m_z = dgMin (p.m_z, minP.m_z); 
			minP.m_w = dgMin (p.m_w, minP.m_w); 

			maxP.m_x = dgMax (p.m_x, maxP.m_x); 
			maxP.m_y = dgMax (p.m_y, maxP.m_y); 
			maxP.m_z = dgMax (p.m_z, maxP.m_z); 
			maxP.m_w = dgMax (p.m_w, maxP.m_w); 

			median = median + p;
			varian = varian + p.CompProduct4(p);
		}

		varian = varian.Scale4 (dgFloat32 (count)) - median.CompProduct4(median);

		dgInt32 index = 0;
		dgFloat64 maxVarian = dgFloat64 (-1.0e10f);
		for (dgInt32 i = 0; i < 4; i ++) {
			if (varian[i] > maxVarian) {
				index = i;
				maxVarian = varian[i];
			}
		}
		dgBigVector center = median.Scale4 (dgFloat64 (1.0f) / dgFloat64 (count));

		dgFloat64 test = center[index];

		dgInt32 i0 = 0;
		dgInt32 i1 = count - 1;
		do {    
			for (; i0 <= i1; i0 ++) {
				dgFloat64 val = points[i0][index];
				if (val > test) {
					break;
				}
			}

			for (; i1 >= i0; i1 --) {
				dgFloat64 val = points[i1][index];
				if (val < test) {
					break;
				}
			}

			if (i0 < i1)	{
				dgSwap(points[i0], points[i1]);
				i0++; 
				i1--;
			}
		} while (i0 <= i1);

		if (i0 == 0){
			i0 = count / 2;
		}
		if (i0 >= (count - 1)){
			i0 = count / 2;
		}

		tree = new (*memoryPool) dgAABBPointTree4d;
		*memoryPool += sizeof (dgAABBPointTree4d);
		maxMemSize -= sizeof (dgAABBPointTree4d);
		dgAssert (maxMemSize >= 0);

		dgAssert (i0);
		dgAssert (count - i0);

		tree->m_left = BuildTree (tree, points, i0, baseIndex, memoryPool, maxMemSize);
		tree->m_right = BuildTree (tree, &points[i0], count - i0, i0 + baseIndex, memoryPool, maxMemSize);
	}

	dgAssert (tree);
	tree->m_parent = parent;
	tree->m_box[0] = minP - dgBigVector (dgFloat64 (1.0e-3f), dgFloat64 (1.0e-3f), dgFloat64 (1.0e-3f), dgFloat64 (1.0e-3f));
	tree->m_box[1] = maxP + dgBigVector (dgFloat64 (1.0e-3f), dgFloat64 (1.0e-3f), dgFloat64 (1.0e-3f), dgFloat64 (1.0e-3f));
	return tree;
}