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
}
dgInt32 dgDelaunayTetrahedralization::AddVertex(const dgBigVector& vertex)
{
#ifdef _WIN32
  dgUnsigned32 controlWorld = dgControlFP (0xffffffff, 0);
  dgControlFP(_PC_53, _MCW_PC);
#endif

  dgBigVector p(vertex);
  p.m_w = p % p;
  dgInt32 index = dgConvexHull4d::AddVertex(p);

#ifdef _WIN32
  dgControlFP(controlWorld, _MCW_PC);
#endif
  return index;
}
void dgWorld::UpdateCollision ()
{
	dgFloat32 timestep;
	_ASSERTE (m_inUpdate == 0);

	
	m_threadsManager.ClearTimers();
	memset (m_perfomanceCounters, 0, sizeof (m_perfomanceCounters));
	dgUnsigned32 ticks = m_getPerformanceCount();


	m_inUpdate ++;
	_ASSERTE (m_numberOfTheads  >= 1);

#if (defined (_WIN_32_VER) || defined (_WIN_64_VER))
	#ifndef __USE_DOUBLE_PRECISION__
		dgUnsigned32 controlWorld = dgControlFP (0xffffffff, 0);
		dgControlFP (_PC_53, _MCW_PC);
	#endif
#endif

	timestep = dgFloat32 (0.0f);

	if (m_cpu == dgSimdPresent) {
#ifdef DG_BUILD_SIMD_CODE	
		simd_env rounding;
		rounding = simd_get_ctrl();
		simd_set_FZ_mode();

		UpdateContactsSimd (timestep, true);
		simd_set_ctrl (rounding);
#endif

	} else {
		UpdateContacts (timestep, true);
	}
	m_inUpdate --;

#if (defined (_WIN_32_VER) || defined (_WIN_64_VER))
	#ifndef __USE_DOUBLE_PRECISION__
		dgControlFP (controlWorld, _MCW_PC);
	#endif
#endif

	m_perfomanceCounters[m_worldTicks] = m_getPerformanceCount() - ticks;
}
Exemple #4
0
void dgThreads::DoWork(dgInt32 mythreadIndex)
{
  dgWorkerThread* job;

#ifdef _WIN32
#ifndef __USE_DOUBLE_PRECISION__
  dgUnsigned32 controlWorld;
  controlWorld = dgControlFP (0xffffffff, 0);
  dgControlFP(_PC_53, _MCW_PC);
#endif
#endif

  if (!m_getPerformanceCount)
  {
    while (GetWork(&job))
    {
      job->ThreadExecute();
      dgInterlockedDecrement(&m_workInProgress);
    }
  }
  else
  {
    while (GetWork(&job))
    {
      dgUnsigned32 ticks = m_getPerformanceCount();

      job->ThreadExecute();
      dgInterlockedDecrement(&m_workInProgress);

      m_localData[mythreadIndex].m_ticks += (m_getPerformanceCount() - ticks);
    }
  }

#ifdef _WIN32
#ifndef __USE_DOUBLE_PRECISION__
  dgControlFP(controlWorld, _MCW_PC);
#endif
#endif

}
dgDelaunayTetrahedralization::dgDelaunayTetrahedralization(
    dgMemoryAllocator* const allocator, const dgFloat64* const vertexCloud,
    dgInt32 count, dgInt32 strideInByte, dgFloat64 distTol) :
    dgConvexHull4d(allocator)
{
#ifdef _WIN32
  dgUnsigned32 controlWorld = dgControlFP (0xffffffff, 0);
  dgControlFP(_PC_53, _MCW_PC);
#endif

  dgStack<dgBigVector> pool(count);

  dgBigVector* const points = &pool[0];
  dgInt32 stride = dgInt32(strideInByte / sizeof(dgFloat64));
  for (dgInt32 i = 0; i < count; i++)
  {
    volatile float x = float(vertexCloud[i * stride + 0]);
    volatile float y = float(vertexCloud[i * stride + 1]);
    volatile float z = float(vertexCloud[i * stride + 2]);
    points[i] = dgBigVector(x, y, z, x * x + y * y + z * z);
  }

  dgInt32 oldCount = count;
  BuildHull(allocator, &pool[0], count, distTol);
#if 1
//	if ((oldCount > m_count) && (m_count >= 4)) {
  if (oldCount > m_count)
  {
    // this is probably a regular convex solid, which will have a zero volume hull
    // add the rest of the points by incremental insertion with small perturbation
    dgInt32 hullCount = m_count;

    for (dgInt32 i = 0; i < count; i++)
    {
      bool inHull = false;
      const dgHullVector* const hullPoints = &m_points[0];
      for (dgInt32 j = 0; j < hullCount; j++)
      {
        if (hullPoints[j].m_index == i)
        {
          inHull = true;
          break;
        }
      }
      if (!inHull)
      {
        dgBigVector q(points[i]);
        dgInt32 index = AddVertex(q);
        if (index == -1)
        {
          q.m_x += dgFloat64(1.0e-3f);
          q.m_y += dgFloat64(1.0e-3f);
          q.m_z += dgFloat64(1.0e-3f);
          index = AddVertex(q);
          _ASSERTE(index != -1);
        }_ASSERTE(index != -1);
//				m_points[index] = points[i];
        m_points[index].m_index = i;
      }
    }
  }
#else
  if (oldCount > m_count)
  {
    // this is probably a regular convex solid, which will have a zero volume hull
    // perturbate a point and try again
    dgBigVector p (points[0]);
    points[0].m_x += dgFloat64 (1.0e-0f);
    points[0].m_y += dgFloat64 (1.0e-0f);
    points[0].m_z += dgFloat64 (1.0e-0f);
    points[0].m_w = points[0].m_x * points[0].m_x + points[0].m_y * points[0].m_y + points[0].m_z * points[0].m_z;
    BuildHull (allocator, &pool[0], oldCount, distTol);
    _ASSERTE (oldCount == m_count);
    // restore the old point
    //points[0].m_w = points[0].m_x * points[0].m_x + points[0].m_y * points[0].m_y + points[0].m_z * points[0].m_z;
  }
#endif

#ifdef _DEBUG
  SortVertexArray();
#endif

#ifdef _WIN32
  dgControlFP(controlWorld, _MCW_PC);
#endif
}
void dgWorld::Update (dgFloat32 timestep)
{
	dgUnsigned32 ticks;
//timestep = 1.0f/ 60.0f;
//timestep = 1.0f/ 120.0f;
//timestep = 1.0f/ 180.0f;
//timestep = 1.0f/ 240.0f;
//timestep = 1.0f/ 300.0f;
//timestep = 1.0f/ 600.0f;
//timestep = 1.0f/ 1000.0f;

//m_cpu = dgNoSimdPresent;
//m_cpu = dgSimdPresent;
//m_solverMode = 1;

//xxxxx();

//static int xxx;
//dgTrace (("pass %d\n", xxx));
//xxx ++;

//m_cpu = dgNoSimdPresent;
	#ifdef _LINUX_VER
//		m_cpu = dgNoSimdPresent;
	#endif

	_ASSERTE (m_inUpdate == 0);

	m_threadsManager.ClearTimers();
	memset (m_perfomanceCounters, 0, sizeof (m_perfomanceCounters));

	ticks = m_getPerformanceCount();

	m_destroyeddBodiesPool.m_count = 0;
	
	m_inUpdate ++;
	_ASSERTE (m_numberOfTheads  >= 1);

#if (defined (_WIN_32_VER) || defined (_WIN_64_VER))
	#ifndef __USE_DOUBLE_PRECISION__
		dgUnsigned32 controlWorld = dgControlFP (0xffffffff, 0);
		dgControlFP (_PC_53, _MCW_PC);
	#endif
#endif

	if (m_cpu == dgSimdPresent) {
#ifdef DG_BUILD_SIMD_CODE	
			simd_env rounding = simd_get_ctrl();
			simd_set_FZ_mode();

			UpdateContactsSimd (timestep, false);
			m_dynamicSolver.UpdateDynamics (this, 1, timestep);

			simd_set_ctrl (rounding);
#endif

	} else {
		UpdateContacts (timestep, false);
		m_dynamicSolver.UpdateDynamics (this, 0, timestep);
	}
	m_inUpdate --;


#if (defined (_WIN_32_VER) || defined (_WIN_64_VER))
	#ifndef __USE_DOUBLE_PRECISION__
		dgControlFP (controlWorld, _MCW_PC);
	#endif
#endif

	if (m_destroyBodyByExeciveForce) {
		for (dgInt32 i = 0; i < m_destroyeddBodiesPool.m_count; i ++) {
			m_destroyBodyByExeciveForce (m_destroyeddBodiesPool.m_bodies[i], m_destroyeddBodiesPool.m_joint[i]);
		}
	}


	m_perfomanceCounters[m_worldTicks] = m_getPerformanceCount() - ticks;
}