Exemplo n.º 1
0
hkpShape* vHavokShapeFactory::CreateConvexShapeFromStaticMeshInstances(const VisStaticMeshInstCollection &meshInstances, hkvMat4 &refTransform, bool shrinkByCvxRadius)
{
  VVERIFY_OR_RET_VAL(meshInstances.GetLength()==1, NULL);

  // Get the collision mesh for the static mesh instance
  VisStaticMeshInstance_cl *pMeshInstance = meshInstances[0];
  VisStaticMesh_cl *pMesh = pMeshInstance->GetMesh();
  IVCollisionMesh *pColMesh = pMesh->GetCollisionMesh(true, true);
  VVERIFY_OR_RET_VAL(pColMesh!=NULL, NULL);

  // We transform each static mesh into the reference space.
  hkvMat4 mTransform = refTransform;
  mTransform = mTransform.multiply (pMeshInstance->GetTransform());

  hkGeometry geom;
  int iNumColMeshes = hkvMath::Max(pColMesh->GetSubmeshCount(), 1);
  for (int i=0;i<iNumColMeshes;i++)
    BuildGeomFromCollisionMesh(pColMesh, i, mTransform, false, geom);
 
  // Set the build configuration to set planes equations and connectivity automatically
  hkpConvexVerticesShape::BuildConfig config;
  config.m_createConnectivity = true;
  config.m_shrinkByConvexRadius = shrinkByCvxRadius;

  hkStridedVertices stridedVerts;
  stridedVerts.m_numVertices = geom.m_vertices.getSize();
  stridedVerts.m_striding    = sizeof(hkVector4);
  stridedVerts.m_vertices    = (const hkReal*)geom.m_vertices.begin();

  // Create convex shape
  hkvConvexVerticesShape *pConvexShape = new hkvConvexVerticesShape(pColMesh->GetFileTime(), stridedVerts, config);
  
  return pConvexShape;
}
Exemplo n.º 2
0
void vHavokStaticMesh::UpdateVision2Havok()
{
  VVERIFY_OR_RET(m_staticMeshes.GetLength() >= 1 && m_pRigidBody);

  int iCount = m_staticMeshes.GetLength();
  for (int i=0;i<iCount;i++)
  {
    // since collision mesh does not provide a bounding box, use bounding box of render mesh as approximation
    const hkvAlignedBBox& bbox = m_staticMeshes[i]->GetBoundingBox();
	hkVector4 bbox_min; vHavokConversionUtils::VisVecToPhysVec_noscale(bbox.m_vMin, bbox_min);
	hkVector4 bbox_max; vHavokConversionUtils::VisVecToPhysVec_noscale(bbox.m_vMax, bbox_max);
	hkVector4 bbox_extent; bbox_extent.setSub(bbox_max,bbox_min); bbox_extent.mul(vHavokConversionUtils::GetVision2HavokScaleSIMD());

	hkVector4 meshTol; meshTol.setAll(hkReal(HKVIS_MESH_SHAPE_TOLERANCE));
	hkVector4Comparison::Mask largeEnough = bbox_extent.greaterEqual(meshTol).getMask<hkVector4ComparisonMask::MASK_XYZ>();
	if (hkMath::countBitsSet(largeEnough) < 2)
    {
      Vision::Error.Warning("Attempted to create a vHavokStaticMesh with undersized extents (%.4f, %4f, %.4f)", 
							bbox_extent(0), bbox_extent(1), bbox_extent(2));
      return;
    }
  }

  // We use the first static mesh instance as origin reference
  VisStaticMeshInstance_cl *pMeshInstance = m_staticMeshes[0];

  // Get the static mesh instance position and rotation
  hkMatrix4 mTransform;
  vHavokConversionUtils::VisMatrixToHkMatrix(pMeshInstance->GetTransform(), mTransform, false, false, true);

  // Split the rotation into scale and normal matrix
  hkRotation mRotation; 
  mRotation.setCols(mTransform.getColumn<0>(),mTransform.getColumn<1>(),mTransform.getColumn<2>());
  hkVector4 vScale;
  vScale.set(mRotation.getColumn<0>().normalizeWithLength<3>(),
			 mRotation.getColumn<1>().normalizeWithLength<3>(),
			 mRotation.getColumn<2>().normalizeWithLength<3>(),
			 hkSimdReal_1);
  
  bool bUpdateDebugRendering = false;

  //Check here if we need to recalculate the precomputed collision mesh
  //should only happen inside the editor
  //if((vScale.x != m_vScale.x || vScale.y != m_vScale.y || vScale.z != m_vScale.z) && m_pRigidBody != NULL)
  hkVector4 mvScale; vHavokConversionUtils::VisVecToPhysVec_noscale(m_vScale,mvScale);
  if (!vScale.allEqual<3>(mvScale, hkSimdReal::fromFloat(HKVMATH_LARGE_EPSILON)) && (m_pRigidBody != NULL))
  {
    // Keep our object alive
    VSmartPtr<vHavokStaticMesh> keepAlive = this;

    RemoveHkRigidBody(); //Remove the old collision object
    CreateHkRigidBody(); //Create a new one (because the scale changed)
    VASSERT_MSG(m_pRigidBody != NULL, "Creating new rigid body failed");
	vHavokConversionUtils::PhysVecToVisVec_noscale(vScale, m_vScale);

    bUpdateDebugRendering = true;
  }

  // Set the transformation in Havok
  hkTransform hkTfOut;
  hkTfOut.setRotation(mRotation);
  hkTfOut.getTranslation().setMul(mTransform.getColumn<3>(),vHavokConversionUtils::GetVision2HavokScaleSIMD());
  m_pRigidBody->setTransform(hkTfOut);

  if (bUpdateDebugRendering)
  {
    SetDebugRendering (false);
  }
}