diff options
Diffstat (limited to 'NvCloth/src/ClothClone.h')
| -rw-r--r-- | NvCloth/src/ClothClone.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/NvCloth/src/ClothClone.h b/NvCloth/src/ClothClone.h new file mode 100644 index 0000000..bdfdb2d --- /dev/null +++ b/NvCloth/src/ClothClone.h @@ -0,0 +1,230 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +#include "../SwFactory.h" +#include "../SwFabric.h" +#include "../SwCloth.h" + +#include "../ClothImpl.h" +#include "../ClothBase.h" +#include "NvCloth/Allocator.h" + +namespace nv +{ +namespace cloth +{ +class DxFactory; +class CuFactory; + +// make range from vector +template <typename T, typename A> +Range<T> makeRange(physx::shdfnd::Array<T, A>& vec) +{ + T* ptr = vec.empty() ? 0 : vec.begin(); + return Range<T>(ptr, ptr + vec.size()); +} + +template <typename T, typename A> +Range<const T> makeRange(const physx::shdfnd::Array<T, A>& vec) +{ + const T* ptr = vec.empty() ? 0 : vec.begin(); + return Range<const T>(ptr, ptr + vec.size()); +} + +// fabric conversion +template <typename SrcClothType, typename DstFactoryType> +typename DstFactoryType::FabricType* convertFabric(const SrcClothType& srcFabric, DstFactoryType& dstFactory) +{ + typedef typename DstFactoryType::FabricType DstFabricType; + + // see if dstFactory already has a Fabric with this id + DstFabricType* const* fIt = dstFactory.mFabrics.begin(); + DstFabricType* const* fEnd = dstFactory.mFabrics.end(); + for (; fIt != fEnd; ++fIt) + if ((*fIt)->mId == srcFabric.mId) + { + (*fIt)->incRefCount(); + return *fIt; // found id, return existing fabric + } + + // fabric does not exist so create a new one + Vector<uint32_t>::Type phaseIndices(srcFabric.getNumPhases()); + Vector<uint32_t>::Type sets(srcFabric.getNumSets()); + Vector<float>::Type restvalues(srcFabric.getNumRestvalues()); + Vector<float>::Type stiffnessValues(srcFabric.getNumStiffnessValues()); + Vector<uint32_t>::Type indices(srcFabric.getNumIndices()); + Vector<uint32_t>::Type anchors(srcFabric.getNumTethers()); + Vector<float>::Type tetherLengths(srcFabric.getNumTethers()); + Vector<uint32_t>::Type triangles(srcFabric.getNumTriangles() * 3); + + Range<uint32_t> phaseIndexRange = makeRange(phaseIndices); + Range<float> restvalueRange = makeRange(restvalues); + Range<float> stiffnessValueRange = makeRange(stiffnessValues); + Range<uint32_t> setRange = makeRange(sets); + Range<uint32_t> indexRange = makeRange(indices); + Range<uint32_t> anchorRange = makeRange(anchors); + Range<float> lengthRange = makeRange(tetherLengths); + Range<uint32_t> triangleRange = makeRange(triangles); + + srcFabric.mFactory.extractFabricData(srcFabric, phaseIndexRange, setRange, restvalueRange, stiffnessValueRange, indexRange, anchorRange, + lengthRange, triangleRange); + + DstFabricType* dstFabric = + static_cast<DstFabricType*>(dstFactory.createFabric(srcFabric.mNumParticles, phaseIndexRange, setRange, restvalueRange, stiffnessValueRange, + indexRange, anchorRange, lengthRange, triangleRange)); + + // give new fabric the same id as the source so it can be matched + dstFabric->mId = srcFabric.mId; + + return dstFabric; +} + +inline Range<const PhaseConfig> getPhaseConfigs(const SwCloth& cloth) +{ + return makeRange(cloth.mPhaseConfigs); +} +inline void setPhaseConfigs(SwCloth& cloth, Range<const PhaseConfig> phaseConfigs) +{ + cloth.mPhaseConfigs.assign(phaseConfigs.begin(), phaseConfigs.end()); +} +inline Range<const physx::PxVec4> getParticleAccelerations(const SwCloth& cloth) +{ + return makeRange(cloth.mParticleAccelerations); +} +inline Range<const uint32_t> getSelfCollisionIndices(const SwCloth& cloth) +{ + return makeRange(cloth.mSelfCollisionIndices); +} + +// cloth conversion +template <typename DstFactoryType, typename SrcImplType> +typename DstFactoryType::ImplType* convertCloth(DstFactoryType& dstFactory, const SrcImplType& srcImpl) +{ + typedef typename DstFactoryType::FabricType DstFabricType; + typedef typename DstFactoryType::ImplType DstImplType; + typedef typename DstImplType::ClothType DstClothType; + typedef typename SrcImplType::ClothType SrcClothType; + + const SrcClothType& srcCloth = srcImpl.mCloth; + const Factory& srcFactory = srcCloth.mFactory; + + typename DstClothType::ContextLockType dstLock(dstFactory); + typename SrcClothType::ContextLockType srcLock(srcCloth.mFactory); + + // particles + MappedRange<const physx::PxVec4> curParticles = srcImpl.getCurrentParticles(); + + // fabric + DstFabricType& dstFabric = *convertFabric(srcCloth.mFabric, dstFactory); + + // create new cloth + DstImplType* dstImpl = static_cast<DstImplType*>(dstFactory.createCloth(curParticles, dstFabric)); + DstClothType& dstCloth = dstImpl->mCloth; + dstFabric.decRefCount(); + + // copy across common parameters + copy(dstCloth, srcCloth); + + // copy across previous particles + MappedRange<const physx::PxVec4> prevParticles = srcImpl.getPreviousParticles(); + memcpy(dstImpl->getPreviousParticles().begin(), prevParticles.begin(), prevParticles.size() * sizeof(physx::PxVec4)); + + // copy across transformed phase configs + setPhaseConfigs(dstCloth, getPhaseConfigs(srcCloth)); + + // collision data + Vector<physx::PxVec4>::Type spheres(srcImpl.getNumSpheres(), physx::PxVec4(0.0f)); + physx::PxVec4* spherePtr = spheres.empty() ? 0 : &spheres.front(); + Range<physx::PxVec4> sphereRange(spherePtr, spherePtr + spheres.size()); + Vector<uint32_t>::Type capsules(srcImpl.getNumCapsules() * 2); + Range<uint32_t> capsuleRange = makeRange(capsules); + Vector<physx::PxVec4>::Type planes(srcImpl.getNumPlanes(), physx::PxVec4(0.0f)); + physx::PxVec4* planePtr = planes.empty() ? 0 : &planes.front(); + Range<physx::PxVec4> planeRange(planePtr, planePtr + planes.size()); + Vector<uint32_t>::Type convexes(srcImpl.getNumConvexes()); + Range<uint32_t> convexRange = makeRange(convexes); + Vector<physx::PxVec3>::Type triangles(srcImpl.getNumTriangles() * 3, physx::PxVec3(0.0f)); + physx::PxVec3* trianglePtr = triangles.empty() ? 0 : &triangles.front(); + Range<physx::PxVec3> triangleRange(trianglePtr, trianglePtr + triangles.size()); + + srcFactory.extractCollisionData(srcImpl, sphereRange, capsuleRange, planeRange, convexRange, triangleRange); + dstImpl->setSpheres(sphereRange, 0, 0); + dstImpl->setCapsules(capsuleRange, 0, 0); + dstImpl->setPlanes(planeRange, 0, 0); + dstImpl->setConvexes(convexRange, 0, 0); + dstImpl->setTriangles(triangleRange, 0, 0); + + // motion constraints, copy directly into new cloth buffer + if (srcImpl.getNumMotionConstraints()) + srcFactory.extractMotionConstraints(srcImpl, dstImpl->getMotionConstraints()); + + // separation constraints, copy directly into new cloth buffer + if (srcImpl.getNumSeparationConstraints()) + srcFactory.extractSeparationConstraints(srcImpl, dstImpl->getSeparationConstraints()); + + // particle accelerations + if (srcImpl.getNumParticleAccelerations()) + { + Range<const physx::PxVec4> accelerations = getParticleAccelerations(srcCloth); + memcpy(dstImpl->getParticleAccelerations().begin(), accelerations.begin(), + accelerations.size() * sizeof(physx::PxVec4)); + } + + // self-collision indices + dstImpl->setSelfCollisionIndices(getSelfCollisionIndices(srcCloth)); + + // rest positions + Vector<physx::PxVec4>::Type restPositions(srcImpl.getNumRestPositions()); + srcFactory.extractRestPositions(srcImpl, makeRange(restPositions)); + dstImpl->setRestPositions(makeRange(restPositions)); + + // virtual particles + if (srcImpl.getNumVirtualParticles()) + { + Vector<Vec4u>::Type indices(srcImpl.getNumVirtualParticles()); + Vector<physx::PxVec3>::Type weights(srcImpl.getNumVirtualParticleWeights(), physx::PxVec3(0.0f)); + + uint32_t(*indicesPtr)[4] = indices.empty() ? 0 : &array(indices.front()); + Range<uint32_t[4]> indicesRange(indicesPtr, indicesPtr + indices.size()); + + physx::PxVec3* weightsPtr = weights.empty() ? 0 : &weights.front(); + Range<physx::PxVec3> weightsRange(weightsPtr, weightsPtr + weights.size()); + + srcFactory.extractVirtualParticles(srcImpl, indicesRange, weightsRange); + + dstImpl->setVirtualParticles(indicesRange, weightsRange); + } + + return dstImpl; +} + +} // namespace cloth +} // namespace nv |