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;
}
void VMeshPaintingComponent::MarkOwnerBoundingBoxDirty()
{
  if (g_bComponentsThroughUI)
    return;

  VisStaticMeshInstance_cl *pMesh = (VisStaticMeshInstance_cl *)GetOwner();
  if (pMesh==NULL)
    return;
  m_CurrentBBox = pMesh->GetBoundingBox();
  VEditableTerrain::AddDirtyVegetationRangeAllTerrains(m_CurrentBBox);
}
void VMeshPaintingComponent::OnOwnerTransformationChanged()
{
  VisStaticMeshInstance_cl *pMesh = (VisStaticMeshInstance_cl *)GetOwner();
  if (pMesh==NULL)
    return;

  // old and new location is dirty
  hkvAlignedBBox newBBox = pMesh->GetBoundingBox();
  if (newBBox!=m_CurrentBBox)
  {
    if (newBBox.isValid())
      VEditableTerrain::AddDirtyVegetationRangeAllTerrains(newBBox);
    if (m_CurrentBBox.isValid())
      VEditableTerrain::AddDirtyVegetationRangeAllTerrains(m_CurrentBBox);
    m_CurrentBBox = newBBox;
    VEditableTerrain::ForceUpdateDecorationReceiverList();
  }

}
Exemplo n.º 4
0
bool MeshLoader::Load(const VSceneListEntry& entry)
{
  Helper::SetupScene(entry);

  // load vmesh
  VisStaticMesh_cl* pRes = VisStaticMesh_cl::GetResourceManager().LoadStaticMeshFile(entry.sScenePath);
  if (pRes == NULL) 
    return false;
  
  // force loading of .colmesh file if it exists
  if (pRes->GetCollisionMesh(true)) 
    hkvLog::Info("Loaded collision mesh");
  else
    hkvLog::Info("No collision mesh loaded");

  // get a instance
  hkvMat4 mTransform;
  VisStaticMeshInstance_cl *pInst = pRes->CreateInstance(mTransform);

  // create the visibility zone
  const hkvAlignedBBox& bbox = pInst->GetBoundingBox();
  int iZones = Vision::GetSceneManager()->GetNumVisibilityZones();
  VisVisibilityZone_cl* pVisZone;
  if (iZones > 0)
  {
    pVisZone = Vision::GetSceneManager()->GetVisibilityZone(0);
  } 
  else
  {
    pVisZone = new VisVisibilityZone_cl(bbox);
    Vision::GetSceneManager()->AddVisibilityZone(pVisZone);
  }

  // add submeshes to vis zone
  for (int i = 0; i < pInst->GetSubmeshInstanceCount(); ++i)
  {
    pVisZone->AddStaticGeometryInstance(pInst->GetSubmeshInstance(i));
  }

  Helper::LookAtBox(bbox);
  return true;
}
Exemplo n.º 5
0
void vHavokStaticMesh::Init(VisStaticMeshInstance_cl &meshInstance)
{
  // Init may only be called once
  VVERIFY_OR_RET(m_bInitialized == false);

  // Add the static mesh instance
  m_staticMeshes.Append(&meshInstance);
  meshInstance.SetPhysicsObject(this);
  m_iNumValidStaticMeshes = 1;
  m_bInitialized = true;

  // Build the Havok shape
  CreateHkRigidBody();
}
Exemplo n.º 6
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);
  }
}
Exemplo n.º 7
0
void vHavokStaticMesh::CreateHkRigidBody()
{
  // Create the Havok shape
  hkpRigidBodyCinfo cInfo;
  cInfo.m_motionType = hkpMotion::MOTION_FIXED;
  
  // We use the first static mesh instance as origin reference
  VisStaticMeshInstance_cl *pMeshInstance = m_staticMeshes[0];
  
  cInfo.m_collisionFilterInfo = pMeshInstance->GetCollisionBitmask();
  if (cInfo.m_collisionFilterInfo & (1<<15))
  {
    cInfo.m_collisionFilterInfo &= ~(1<<15);
    Vision::Error.Warning("vHavok: Static mesh [%s] has outdated collision information. Please reexport scene.", pMeshInstance->GetMesh()->GetFilename());
  }

  // Get the scaling of the first static mesh which is used as a reference
  {
	  hkMatrix4 mTransform;
	  vHavokConversionUtils::VisMatrixToHkMatrix(m_staticMeshes[0]->GetTransform(), mTransform, false, false, true);
	  hkVector4 vScale;
	  vScale.set(	mTransform.getColumn<0>().lengthSquared<3>(),
					mTransform.getColumn<1>().lengthSquared<3>(),
					mTransform.getColumn<2>().lengthSquared<3>(),
					hkSimdReal_1);
	  vScale.setSqrt(vScale);
	  vHavokConversionUtils::PhysVecToVisVec_noscale(vScale,m_vScale);
  }

  // Create the shape. 
  // We can either create the shape from mem, or serialize it in (if cached).
  // Do not set vHavokShapeFactory::VShapeCreationFlags_SHRINK, so back compat. Better to have as an option.
  const int iCreationFlags = (pMeshInstance->GetCollisionBehavior()==VisStaticMeshInstance_cl::VIS_COLLISION_BEHAVIOR_FROMFILE) ? 
                             vHavokShapeFactory::VShapeCreationFlags_ALLOW_PERTRICOLINFO : 0;
  hkRefPtr<hkpShape> spShape = vHavokShapeFactory::CreateShapeFromStaticMeshInstances(m_staticMeshes, iCreationFlags, &m_szShapeCacheId);
  cInfo.m_shape = spShape;

  // When CollisionBehavior_e::FromFile was selected and there is no collisionFilterInfo available from file (due to old vcolmesh format, convex shape),
  // a default collisionFilterInfo will be used.
  if (cInfo.m_collisionFilterInfo==0)
  {
    bool bHasMaterialCacheData = false;
    const hkpShape *pShape = (hkpShape*)spShape.val();
    const hkClass *pClass = pShape->getClassType();
    if (pClass == &hkvBvCompressedMeshShapeClass)
    {
      const hkvBvCompressedMeshShape *pMeshShape = (hkvBvCompressedMeshShape*)(pShape);
      bHasMaterialCacheData = pMeshShape->m_userData != HK_NULL;
    }
    if (!bHasMaterialCacheData)
      cInfo.m_collisionFilterInfo = vHavokPhysicsModule::HK_LAYER_COLLIDABLE_STATIC;
  }
  cInfo.m_numShapeKeysInContactPointProperties = -1; 	// Ensure shape keys are stored.
  m_pRigidBody = new hkpRigidBody(cInfo);

  // Set user data to identify this static mesh during collision detection
  m_pRigidBody->setUserData((hkUlong)vHavokUserDataPointerPair_t::CombineTypeAndPointer(this, V_USERDATA_STATIC));

  // Add our instance to the module
  UpdateVision2Havok();
  m_module.AddStaticMesh(this);
}