void MeshNode::UpdateWorldBounds(){ if(!initialized) return; worldBounds_.center = mul1(transform_, mesh_->localBounds.center); float x, y, z; ExtractScaling(transform_,x,y,z); worldBounds_.radius = mesh_->localBounds.radius * max(max(x,y),z); }
void vHavokShapeFactory::GetHktDependencies(VResourceSnapshot &snapshot, VisStaticMeshInstance_cl *pMeshInstance) { VASSERT(pMeshInstance != NULL); // Get scale hkvVec3 vScale(hkvNoInitialization); ExtractScaling(pMeshInstance->GetTransform(), vScale); // There is no real way to figure out if a convex or mesh shape is required and the filename is based on that. // So try them both. // Convex version { VStaticString<FS_MAX_PATH> szCachedShapeName(pMeshInstance->GetMesh()->GetFilename()); bool shrinkToFit = false; //how do if true / can it be true for static mesh? vHavokCachedShape::GetConvexShapePath(szCachedShapeName, vScale, shrinkToFit); IVFileInStream *pIn = Vision::File.Open(szCachedShapeName); if (pIn) { snapshot.AddFileDependency(pMeshInstance->GetMesh(), szCachedShapeName, pIn->GetSize() ); pIn->Close(); return; } } // Mesh version { VStaticString<FS_MAX_PATH> szCachedShapeName(pMeshInstance->GetMesh()->GetFilename()); vHavokCachedShape::GetMeshShapePath(szCachedShapeName, vScale, pMeshInstance->GetCollisionBehavior(), pMeshInstance->GetWeldingType()); IVFileInStream *pIn = Vision::File.Open(szCachedShapeName); if (pIn) { snapshot.AddFileDependency(pMeshInstance->GetMesh(), szCachedShapeName, pIn->GetSize() ); pIn->Close(); return; } } }
hkRefNew<hkpShape> vHavokShapeFactory::CreateShapeFromStaticMeshInstances(const VisStaticMeshInstCollection &meshInstances, int iCreationFlags, const char **szShapeCacheId) { int iCount = meshInstances.GetLength(); VVERIFY_OR_RET_VAL(iCount>0 && szShapeCacheId!=NULL, NULL); // Actual mesh scale, which is only used for caching. hkvVec3 vScale(hkvNoInitialization); ExtractScaling(meshInstances[0]->GetTransform(), vScale); char szShapeId[512]; const bool bAllowStaticMeshCaching = vHavokPhysicsModule_GetDefaultWorldRuntimeSettings().m_bEnableShapeCaching==TRUE; const vHavokPhysicsModule *pModule = vHavokPhysicsModule::GetInstance(); VASSERT(pModule != NULL); const bool bForceHktShapeCaching = pModule->IsHktShapeCachingEnforced(); // For single mesh instances the per instance welding type is used. For merged mesh instances the global merged welding type is used. VisWeldingType_e eWeldingType = (iCount==1) ? meshInstances[0]->GetWeldingType() : (VisWeldingType_e)vHavokPhysicsModule_GetWorldSetupSettings().m_iMergedStaticWeldingType; const bool bAllowPerTriCollisionInfo = iCreationFlags & VShapeCreationFlags_ALLOW_PERTRICOLINFO; const bool bShrinkByCvxRadius = iCreationFlags & VShapeCreationFlags_SHRINK; // Check whether shape has been already cached for this mesh with the respective scaling. // We are just caching single static mesh instances and no static mesh collections. hkpShape *pCachedShape = HK_NULL; if (iCount == 1) { // first, find the convex version GetIDStringForConvexShape(szShapeId, meshInstances[0]->GetMesh()->GetFilename(), vScale, bShrinkByCvxRadius); pCachedShape = FindShape(szShapeId, szShapeCacheId); if (!pCachedShape) { // then find the mesh version GetIDStringForMeshShape(szShapeId, meshInstances[0]->GetMesh()->GetFilename(), vScale, meshInstances[0]->GetCollisionBehavior(), eWeldingType); pCachedShape = FindShape(szShapeId, szShapeCacheId); } if (pCachedShape) { pCachedShape->addReference(); return pCachedShape; } if (bAllowStaticMeshCaching) { // first, find the convex version pCachedShape = vHavokCachedShape::LoadConvexShape(meshInstances[0]->GetMesh(), vScale, bShrinkByCvxRadius); if (pCachedShape) { *szShapeCacheId = AddShape(szShapeId, pCachedShape); #ifdef HK_DEBUG_SLOW const hkClass* loadedClassType = hkVtableClassRegistry::getInstance().getClassFromVirtualInstance(pCachedShape); HK_ASSERT2(0x5432c902, loadedClassType && (hkString::strCmp( loadedClassType->getName(), "hkvConvexVerticesShape" ) == 0), "Serialized in a unexpected cached Havok shape type!"); #endif return pCachedShape; } else { // then find the mesh version pCachedShape = vHavokCachedShape::LoadMeshShape(meshInstances[0]->GetMesh(), vScale, meshInstances[0]->GetCollisionBehavior(), eWeldingType); } if (pCachedShape ) { *szShapeCacheId = AddShape(szShapeId, pCachedShape); #ifdef HK_DEBUG_SLOW const hkClass* loadedClassType = hkVtableClassRegistry::getInstance().getClassFromVirtualInstance(pCachedShape); HK_ASSERT2(0x5432c902, loadedClassType && (hkString::strCmp( loadedClassType->getName(), "hkvBvCompressedMeshShape" ) == 0), "Serialized in a unexpected cached Havok shape type!"); #endif hkvBvCompressedMeshShape *pCompressedMeshShape = reinterpret_cast<hkvBvCompressedMeshShape*>(pCachedShape); pCompressedMeshShape->SetupMaterials(); return pCachedShape; } else if(!Vision::Editor.IsInEditor() && !bForceHktShapeCaching) { Vision::Error.Warning("Cached HKT file for %s is missing. Please generate HKT file (see documentation for details).", meshInstances[0]->GetMesh()->GetFilename()); } } } // Get the reference transformation. We use the first static mesh as reference // transformation, and thus as the position of the corresponding rigid body. hkvMat4 referenceTransform = meshInstances[0]->GetTransform(); // Remove any scaling from the reference matrix. This one has to be applied to // the Havok shapes, and thus needs to be part of the mesh transforms. referenceTransform.setScalingFactors(hkvVec3 (1)); // We need the inverse referenceTransform to transform each instance into reference space referenceTransform.invert(); referenceTransform.setRow (3, hkvVec4 (0, 0, 0, 1)); // Determine collision type from first static mesh instance. const VisStaticMeshInstance_cl *pMeshInstance = meshInstances[0]; VisStaticMesh_cl *pMesh = pMeshInstance->GetMesh(); IVCollisionMesh *pColMesh = pMesh->GetCollisionMesh(true, true); const bool bIsConvex = pColMesh->GetType()==VIS_COLMESH_GEOTYPE_CONVEXHULL; // Only create a convex shape if a single mesh instance is used, since otherwise merging multiple mesh instances in one single convex hull // will provide in most cases not the desired behavior. Moreover we can only create either a convex hull or a concave mesh shape, therefore // mesh instances with different collision type can't be merged into one shape. hkpShape *pShape = (bIsConvex && iCount==1) ? CreateConvexShapeFromStaticMeshInstances(meshInstances, referenceTransform, bShrinkByCvxRadius) : CreateMeshShapeFromStaticMeshInstances(meshInstances, referenceTransform, bAllowPerTriCollisionInfo, eWeldingType); // We are just caching single static mesh instances and no static mesh collections. if (iCount == 1) { *szShapeCacheId = AddShape(szShapeId, pShape); // Only cache shape to HKT file when inside vForge or when enforced. if ((Vision::Editor.IsInEditor() && bAllowStaticMeshCaching) || bForceHktShapeCaching) { if (bIsConvex) vHavokCachedShape::SaveConvexShape(meshInstances[0]->GetMesh(), vScale, bShrinkByCvxRadius, (hkvConvexVerticesShape*)pShape); else vHavokCachedShape::SaveMeshShape(meshInstances[0]->GetMesh(), vScale, meshInstances[0]->GetCollisionBehavior(), eWeldingType, (hkvBvCompressedMeshShape*)pShape); } } return pShape; }