1#include "NeighborElementQuery.h"
 
    2#include "CollisionDetectionAlgorithm.h"
 
    4#include "Collision/CollisionDetectionBroadPhase.h"
 
    6#include "Primitive/Primitive3D.h"
 
   12    IMPLEMENT_TCLASS(NeighborElementQuery, TDataType)
 
   16        int bodyId1 = INVLIDA_ID;
 
   17        int bodyId2 = INVLIDA_ID;
 
   20    template<typename TDataType>
 
   21    NeighborElementQuery<TDataType>::NeighborElementQuery()
 
   24        this->inCollisionMask()->tagOptional(true);
 
   26        this->inAttribute()->tagOptional(true);
 
   28        mBroadPhaseCD = std::make_shared<CollisionDetectionBroadPhase<TDataType>>();
 
   30        this->varGridSizeLimit()->attach(
 
   31            std::make_shared<FCallBackFunc>(
 
   33                    mBroadPhaseCD->varGridSizeLimit()->setValue(this->varGridSizeLimit()->getValue());
 
   37        this->varSelfCollision()->attach(
 
   38            std::make_shared<FCallBackFunc>(
 
   40                    mBroadPhaseCD->varSelfCollision()->setValue(this->varSelfCollision()->getValue());
 
   44        this->varGridSizeLimit()->setValue(Real(0.011));
 
   45        this->varSelfCollision()->setValue(true);
 
   48    template<typename TDataType>
 
   49    NeighborElementQuery<TDataType>::~NeighborElementQuery()
 
   53    template<typename Real, typename Coord>
 
   54    __global__ void NEQ_SetupAABB(
 
   55        DArray<AABB> boundingBox,
 
   56        DArray<Coord> position,
 
   59        int pId = threadIdx.x + (blockIdx.x * blockDim.x);
 
   60        if (pId >= position.size()) return;
 
   63        Coord p = position[pId];
 
   67        boundingBox[pId] = box;
 
   70    template<typename Box3D>
 
   71    __global__ void NEQ_SetupAABB(
 
   72        DArray<AABB> boundingBox,
 
   74        DArray<Sphere3D> spheres,
 
   76        DArray<Capsule3D> caps,
 
   77        DArray<Triangle3D> tris,
 
   78        ElementOffset elementOffset,
 
   81        uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
 
   82        if (tId >= boundingBox.size()) return;
 
   84        ElementType eleType = elementOffset.checkElementType(tId);
 
   91            box = spheres[tId].aabb();
 
   96            box = boxes[tId - elementOffset.boxIndex()].aabb();
 
  101            box = tets[tId - elementOffset.tetIndex()].aabb();
 
  106            box = caps[tId - elementOffset.capsuleIndex()].aabb();
 
  111            boundary_expand = 0.01;
 
  112            box = tris[tId - elementOffset.triangleIndex()].aabb();
 
  119        box.v0 -= boundary_expand;
 
  120        box.v1 += boundary_expand;
 
  122        boundingBox[tId] = box;
 
  125    __device__ inline bool checkCollision(CollisionMask cType0, CollisionMask cType1, ElementType eleType0, ElementType eleType1)
 
  127        bool canCollide = (cType0 & eleType1) != 0 && (cType1 & eleType0) > 0;
 
  134    template<typename Box3D, typename ContactPair>
 
  135    __global__ void NEQ_Narrow_Count(
 
  137        DArray<ContactPair> nbr_cons,
 
  138        DArray<ContactId> nbr,
 
  139        DArray<CollisionMask> mask,
 
  141        DArray<Sphere3D> spheres,
 
  143        DArray<Real> tets_sdf,
 
  144        DArray<int> tet_body_ids,
 
  145        DArray<TopologyModule::Tetrahedron> tet_element_ids,
 
  146        DArray<Capsule3D> caps,
 
  147        DArray<Triangle3D> triangles,
 
  148        DArray<Attribute> attribute,
 
  149        DArray<Pair<uint, uint>> shape2RigidBodyMapping,
 
  150        ElementOffset elementOffset,
 
  152        bool enableSelfCollision,
 
  153        bool enableCollisionMask)
 
  155        int tId = threadIdx.x + (blockIdx.x * blockDim.x);
 
  156        if (tId >= nbr.size()) return;
 
  158        ContactId ids = nbr[tId];
 
  159        ElementType eleType_i = elementOffset.checkElementType(ids.bodyId1);
 
  160        ElementType eleType_j = elementOffset.checkElementType(ids.bodyId2);
 
  162        TManifold<Real> manifold;
 
  164        // Convert primitive id into rigid body id
 
  165        int mappedId1 = ids.bodyId1 == INVALID ? ids.bodyId1 : shape2RigidBodyMapping[ids.bodyId1].second;
 
  166        int mappedId2 = ids.bodyId2 == INVALID ? ids.bodyId2 : shape2RigidBodyMapping[ids.bodyId2].second;
 
  168        // TODO: check whether it is plausible to define collision mask on rigid bodies
 
  169        CollisionMask mask_i = enableCollisionMask ? mask[mappedId1] : CollisionMask::CT_AllObjects;
 
  170        CollisionMask mask_j = enableCollisionMask ? mask[mappedId2] : CollisionMask::CT_AllObjects;
 
  172        // If two primitives belong to the same rigid body, disable collision detection
 
  173        if (mappedId1 == mappedId2)
 
  176        if (!enableSelfCollision)
 
  178            Attribute att_i = attribute[mappedId1];
 
  179            Attribute att_j = attribute[mappedId2];
 
  181            if (att_i.objectId() == att_j.objectId())
 
  185        if (eleType_i == ET_BOX && eleType_j == ET_BOX && checkCollision(mask_i, mask_j, ET_BOX, ET_BOX))
 
  187            auto boxA = boxes[ids.bodyId1 - elementOffset.boxIndex()];
 
  188            auto boxB = boxes[ids.bodyId2 - elementOffset.boxIndex()];
 
  193            CollisionDetection<Real>::request(manifold, boxA, boxB);
 
  194            //CollisionDetection<Real>::request(manifold, boxA, boxB, dHat, dHat);
 
  195            //printf("Box - Box dHat:%f\n", dHat);
 
  196            //printf("Collision: %d\n", manifold.contactCount);
 
  197            //for (int i = 0; i < manifold.contactCount; i++)
 
  199            //  printf("dep: %f\n", manifold.contacts[i].penetration);
 
  202        else if (eleType_i == ET_SPHERE && eleType_j == ET_BOX && checkCollision(mask_i, mask_j, ET_SPHERE, ET_BOX))
 
  204            auto sphere = spheres[ids.bodyId1];
 
  205            auto box = boxes[ids.bodyId2 - elementOffset.boxIndex()];
 
  207            //sphere.radius += dHat;
 
  208            //box.extent += dHat;
 
  209            //CollisionDetection<Real>::request(manifold, sphere, box);
 
  210            CollisionDetection<Real>::request(manifold, sphere, box, dHat, dHat);
 
  212            //printf("SPhere - Box dHat:%f\n", dHat);
 
  213            //printf("Collision: %d\n", manifold.contactCount);
 
  214            //for (int i = 0; i < manifold.contactCount; i++)
 
  216            //  printf("dep: %f\n", manifold.contacts[i].penetration);
 
  219        else if (eleType_i == ET_BOX && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_BOX, ET_SPHERE))
 
  221            auto box = boxes[ids.bodyId1 - elementOffset.boxIndex()];
 
  222            auto sphere = spheres[ids.bodyId2];
 
  224            //box.extent += dHat;
 
  225            //sphere.radius += dHat;
 
  226            //CollisionDetection<Real>::request(manifold, box, sphere);
 
  227            CollisionDetection<Real>::request(manifold, box, sphere, dHat, dHat);
 
  229            //printf("Box - SPhere dHat:%f\n", dHat);
 
  230            //printf("Collision: %d\n", manifold.contactCount);
 
  231            //for (int i = 0; i < manifold.contactCount; i++)
 
  233            //  printf("dep: %f\n", manifold.contacts[i].penetration);
 
  236        else if (eleType_i == ET_SPHERE && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_SPHERE, ET_SPHERE))
 
  238            auto sphereA = spheres[ids.bodyId1];
 
  239            auto sphereB = spheres[ids.bodyId2];
 
  241            sphereA.radius += dHat;
 
  242            sphereB.radius += dHat;
 
  244            //CollisionDetection<Real>::request(manifold, sphereA, sphereB);
 
  245            CollisionDetection<Real>::request(manifold, sphereA, sphereB, dHat, dHat);
 
  247        else if(eleType_i == ET_TET && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_TET, ET_TET))
 
  249            //TODO: consider dHat
 
  250            auto tetA = tets[ids.bodyId1 - elementOffset.tetIndex()];
 
  251            auto tetB = tets[ids.bodyId2 - elementOffset.tetIndex()];
 
  252            //CollisionDetection<Real>::request(manifold, tetA, tetB);
 
  254            CollisionDetection<Real>::request(manifold, tetA, tetB, dHat, dHat);
 
  256        else if (eleType_i == ET_TET && eleType_j == ET_BOX && checkCollision(mask_i, mask_j, ET_TET, ET_BOX))
 
  258            //TODO: consider dHat
 
  259            auto tetA = tets[ids.bodyId1 - elementOffset.tetIndex()];
 
  260            auto boxB = boxes[ids.bodyId2 - elementOffset.boxIndex()];
 
  261            //CollisionDetection<Real>::request(manifold, tetA, boxB);
 
  263            CollisionDetection<Real>::request(manifold, tetA, boxB, dHat, dHat);
 
  265        else if (eleType_i == ET_BOX && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_BOX, ET_TET))
 
  267            //TODO: consider dHat
 
  268            auto boxA = boxes[ids.bodyId1 - elementOffset.boxIndex()];
 
  269            auto tetB = tets[ids.bodyId2 - elementOffset.tetIndex()];
 
  270            //CollisionDetection<Real>::request(manifold, boxA, tetB);
 
  272            CollisionDetection<Real>::request(manifold, boxA, tetB, dHat, dHat);
 
  274        else if (eleType_i == ET_SPHERE && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_SPHERE, ET_TET))
 
  276            //TODO: consider dHat
 
  277            auto sphere = spheres[ids.bodyId1];
 
  278            auto tet = tets[ids.bodyId2 - elementOffset.tetIndex()];
 
  279            //CollisionDetection<Real>::request(manifold, sphere, tet);
 
  281            CollisionDetection<Real>::request(manifold, sphere, tet, dHat, dHat);
 
  283        else if (eleType_i == ET_TET && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_TET, ET_SPHERE))
 
  285            //TODO: consider dHat
 
  286            auto tet = tets[ids.bodyId1 - elementOffset.tetIndex()];
 
  287            auto sphere = spheres[ids.bodyId2];
 
  288            //CollisionDetection<Real>::request(manifold, tet, sphere);
 
  290            CollisionDetection<Real>::request(manifold, tet, sphere, dHat, dHat);
 
  292        else if (eleType_i == ET_TRI && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_TRI, ET_SPHERE))
 
  294            //TODO: consider dHat
 
  295            auto tri = triangles[ids.bodyId1 - elementOffset.triangleIndex()];
 
  296            auto sphere = spheres[ids.bodyId2];
 
  297            sphere.radius += 0.01f;
 
  298            //CollisionDetection<Real>::request(manifold, sphere, tri);
 
  300            CollisionDetection<Real>::request(manifold, sphere, tri, dHat, dHat);
 
  302        else if (eleType_i == ET_SPHERE && eleType_j == ET_TRI && checkCollision(mask_i, mask_j, ET_SPHERE, ET_TRI))
 
  304            //TODO: consider dHat
 
  305            auto tri = triangles[ids.bodyId2 - elementOffset.triangleIndex()];
 
  306            auto sphere = spheres[ids.bodyId1];
 
  307            sphere.radius += 0.01f;
 
  308            //CollisionDetection<Real>::request(manifold, sphere, tri);
 
  310            CollisionDetection<Real>::request(manifold, sphere, tri, dHat, dHat);
 
  312        else if (eleType_i == ET_TET && eleType_j == ET_TRI && checkCollision(mask_i, mask_j, ET_TET, ET_TRI))
 
  314            //TODO: consider dHat
 
  315            auto tri = triangles[ids.bodyId2 - elementOffset.triangleIndex()];
 
  316            auto tet = tets[ids.bodyId1 - elementOffset.tetIndex()];
 
  317            //CollisionDetection<Real>::request(manifold, tet, tri);
 
  319            CollisionDetection<Real>::request(manifold, tet, tri, dHat, dHat);
 
  321        else if (eleType_i == ET_TRI && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_TRI, ET_TET))
 
  323        //TODO: consider dHat
 
  324            auto tri = triangles[ids.bodyId1 - elementOffset.triangleIndex()];
 
  325            auto tet = tets[ids.bodyId2 - elementOffset.tetIndex()];
 
  326            //CollisionDetection<Real>::request(manifold, tri, tet);
 
  328            CollisionDetection<Real>::request(manifold, tri, tet, dHat, dHat);
 
  331        //Capsule with other primitives
 
  332        else if (eleType_i == ET_TET && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_TET, ET_CAPSULE))      //tet-capsule
 
  334            //TODO: consider dHat
 
  335            auto cap = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
 
  336            auto tet = tets[ids.bodyId1 - elementOffset.tetIndex()];
 
  337             //CollisionDetection<Real>::request(manifold, tet, cap);
 
  339            Segment3D seg = cap.centerline();
 
  340            Real radius = cap.radius;
 
  341            CollisionDetection<Real>::request(manifold, tet, seg, dHat, radius + dHat);
 
  343        else if (eleType_j == ET_TET && eleType_i == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_TET))
 
  345            //TODO: consider dHat
 
  346            auto cap = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
 
  347            auto tet = tets[ids.bodyId2 - elementOffset.tetIndex()];
 
  348            //CollisionDetection<Real>::request(manifold, cap, tet);
 
  350            Segment3D seg = cap.centerline();
 
  351            Real radius = cap.radius;
 
  352            CollisionDetection<Real>::request(manifold, seg, tet, radius + dHat, dHat);
 
  354        else if (eleType_i == ET_CAPSULE && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_CAPSULE))  //capsule-capsule
 
  356            auto cap1 = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
 
  357            auto cap2 = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
 
  359            //cap1.radius += dHat;
 
  360            //cap2.radius += dHat;
 
  361            //CollisionDetection<Real>::request(manifold, cap1, cap2);
 
  363            Segment3D seg1 = cap1.centerline(); Real radius1 = cap1.radius;
 
  364            Segment3D seg2 = cap2.centerline(); Real radius2 = cap2.radius;
 
  365            CollisionDetection<Real>::request(manifold, seg1, seg2, radius1 + dHat, radius2 + dHat);
 
  368        else if (eleType_i == ET_BOX && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_BOX, ET_CAPSULE))          //box-capsule
 
  370            auto cap = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
 
  371            auto box = boxes[ids.bodyId1 - elementOffset.boxIndex()];
 
  373            //cap.radius += dHat;
 
  374            //box.extent += dHat;
 
  375            //CollisionDetection<Real>::request(manifold, box, cap);
 
  377            Segment3D seg = cap.centerline();
 
  378            Real radius = cap.radius;
 
  379            CollisionDetection<Real>::request(manifold, box, seg, dHat, radius + dHat);
 
  381        else if (eleType_j == ET_BOX && eleType_i == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_BOX))
 
  383            auto cap = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
 
  384            auto box = boxes[ids.bodyId2 - elementOffset.boxIndex()];
 
  386            //cap.radius += dHat;
 
  387            //box.extent += dHat;
 
  388            //CollisionDetection<Real>::request(manifold, cap, box);
 
  390            Segment3D seg = cap.centerline();
 
  391            Real radius = cap.radius;
 
  392            CollisionDetection<Real>::request(manifold, seg, box, radius + dHat, dHat);
 
  394        else if (eleType_i == ET_SPHERE && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_SPHERE, ET_CAPSULE))            //sphere-capsule
 
  396            auto cap = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
 
  397            auto sphere = spheres[ids.bodyId1 - elementOffset.sphereIndex()];
 
  399            //cap.radius += dHat;
 
  400            //sphere.radius += dHat;
 
  401            //CollisionDetection<Real>::request(manifold, sphere, cap);
 
  403            Segment3D seg = cap.centerline();
 
  404            Real radius = cap.radius;
 
  405            CollisionDetection<Real>::request(manifold, sphere, seg, dHat, radius + dHat);
 
  408        else if (eleType_j == ET_SPHERE && eleType_i == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_SPHERE))
 
  410            auto cap = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
 
  411            auto sphere = spheres[ids.bodyId2 - elementOffset.sphereIndex()];
 
  413            //cap.radius += dHat;
 
  414            //sphere.radius += dHat;
 
  415            //CollisionDetection<Real>::request(manifold, cap, sphere);
 
  417            Segment3D seg = cap.centerline();
 
  418            Real radius = cap.radius;
 
  419            CollisionDetection<Real>::request(manifold, seg, sphere, radius + dHat, dHat);
 
  422        count[tId] = manifold.contactCount;
 
  424        //printf("%d %d; num: %d \n", mappedId1, mappedId2, manifold.contactCount);
 
  426        int offset = 8 * tId;
 
  427        for (int n = 0; n < manifold.contactCount; n++)
 
  430            //cp.pos1 = manifold.contacts[n].position + dHat * manifold.normal;
 
  431            //cp.pos2 = manifold.contacts[n].position + dHat * manifold.normal;
 
  432            cp.pos1 = manifold.contacts[n].position;
 
  433            cp.pos2 = manifold.contacts[n].position;
 
  434            cp.normal1 = -manifold.normal;
 
  435            cp.normal2 = manifold.normal;
 
  436            cp.bodyId1 = mappedId1;
 
  437            cp.bodyId2 = mappedId2;
 
  438            cp.contactType = ContactType::CT_NONPENETRATION;
 
  439            //cp.interpenetration = -manifold.contacts[n].penetration - 2 * dHat;
 
  440            cp.interpenetration = -manifold.contacts[n].penetration;
 
  441            nbr_cons[offset + n] = cp;
 
  445    template<typename ContactPair>
 
  446    __global__ void NEQ_Narrow_Set(
 
  447        DArray<ContactPair> nbr_cons,
 
  448        DArray<ContactPair> nbr_cons_all,
 
  449        DArray<ContactId> nbr,
 
  453        int tId = threadIdx.x + (blockIdx.x * blockDim.x);
 
  454        if (tId >= nbr.size()) return;
 
  456        ContactId ids = nbr[tId];
 
  458        int offset = prefix[tId];
 
  460        for (int n = 0; n < size; n++)
 
  462            nbr_cons[offset + n] = nbr_cons_all[8 * tId + n];
 
  466    __global__ void CCL_CountListSize(
 
  468        DArrayList<int> contactList)
 
  470        int tId = threadIdx.x + (blockIdx.x * blockDim.x);
 
  471        if (tId >= contactList.size()) return;
 
  473        num[tId] = contactList[tId].size();
 
  476    __global__ void CCL_SetupContactIds(
 
  477        DArray<ContactId> ids,
 
  479        DArrayList<int> contactList)
 
  481        int tId = threadIdx.x + (blockIdx.x * blockDim.x);
 
  482        if (tId >= contactList.size()) return;
 
  484        int base = index[tId];
 
  486        auto& list_i = contactList[tId];
 
  487        for (int j = 0; j < list_i.size(); j++)
 
  491            id.bodyId2 = list_i[j];
 
  497    template<typename TDataType>
 
  498    void NeighborElementQuery<TDataType>::compute()
 
  500        auto inTopo = this->inDiscreteElements()->getDataPtr();
 
  502        if (this->outContacts()->isEmpty())
 
  503            this->outContacts()->allocate();
 
  505        this->outContacts()->clear();
 
  507        int t_num = inTopo->totalSize();
 
  511            auto& contacts = this->outContacts()->getData();
 
  516        if (mQueriedAABB.size() != t_num){
 
  517            mQueriedAABB.resize(t_num);
 
  520        if (mQueryAABB.size() != t_num){
 
  521            mQueryAABB.resize(t_num);
 
  523        //printf("=========== ============= INSIDE SELF COLLISION %d\n", t_num);
 
  524        ElementOffset elementOffset = inTopo->calculateElementOffset();
 
  526        Real dHat = this->varDHead()->getValue();
 
  528        auto& position = inTopo->position();
 
  529        auto& rotation = inTopo->rotation();
 
  531        DArray<Box3D>& boxInGlobal = inTopo->boxesInGlobal();
 
  532        DArray<Sphere3D>& sphereInGlobal = inTopo->spheresInGlobal();
 
  533        DArray<Tet3D>& tetInGlobal = inTopo->tetsInGlobal();
 
  534        DArray<Capsule3D>& capsuleInGlobal = inTopo->capsulesInGlobal();
 
  535        DArray<Triangle3D>& triangleInGlobal = inTopo->trianglesInGlobal();
 
  548        mQueryAABB.assign(mQueriedAABB);
 
  550        mBroadPhaseCD->inSource()->assign(mQueryAABB);
 
  551        mBroadPhaseCD->inTarget()->assign(mQueriedAABB);
 
  553        mBroadPhaseCD->update();
 
  555        auto& contactList = mBroadPhaseCD->outContactList()->getData();
 
  556        if (contactList.elementSize() == 0) {
 
  560        DArray<int> count(contactList.size());
 
  561        cuExecute(contactList.size(),
 
  566        int totalSize = mReduce.accumulate(count.begin(), count.size());
 
  568        if (totalSize <= 0) {
 
  569            this->outContacts()->clear();
 
  573        mScan.exclusive(count);
 
  575        DArray<ContactId> deviceIds(totalSize);
 
  577        cuExecute(contactList.size(),
 
  587        DArray<int> contactNum;
 
  588        DArray<int> contactNumCpy;
 
  590        contactNum.resize(deviceIds.size());
 
  592        contactNumCpy.resize(deviceIds.size());
 
  593        contactNumCpy.reset();
 
  595        DArray<TContactPair<Real>> nbr_cons_tmp;
 
  596        nbr_cons_tmp.resize(deviceIds.size() * 8);
 
  597        nbr_cons_tmp.reset();
 
  599        if (this->inCollisionMask()->isEmpty())
 
  601            DArray<CollisionMask> dummyCollisionMask;
 
  602            if (!this->varSelfCollision()->getValue() && !this->inAttribute()->isEmpty())
 
  604                cuExecute(deviceIds.size(),
 
  614                    inTopo->getTetBodyMapping(),
 
  615                    inTopo->getTetElementMapping(),
 
  618                    this->inAttribute()->getData(),
 
  619                    inTopo->shape2RigidBodyMapping(),
 
  627                DArray<Attribute> dummyAttribute;
 
  628                cuExecute(deviceIds.size(),
 
  638                    inTopo->getTetBodyMapping(),
 
  639                    inTopo->getTetElementMapping(),
 
  643                    inTopo->shape2RigidBodyMapping(),
 
  653            if (!this->varSelfCollision()->getValue() && !this->inAttribute()->isEmpty())
 
  655                cuExecute(deviceIds.size(),
 
  660                    this->inCollisionMask()->getData(),
 
  665                    inTopo->getTetBodyMapping(),
 
  666                    inTopo->getTetElementMapping(),
 
  669                    this->inAttribute()->getData(),
 
  670                    inTopo->shape2RigidBodyMapping(),
 
  678                DArray<Attribute> dummyAttribute;
 
  679                cuExecute(deviceIds.size(),
 
  684                    this->inCollisionMask()->getData(),
 
  689                    inTopo->getTetBodyMapping(),
 
  690                    inTopo->getTetElementMapping(),
 
  694                    inTopo->shape2RigidBodyMapping(),
 
  702        contactNumCpy.assign(contactNum);
 
  704        int sum = mReduce.accumulate(contactNum.begin(), contactNum.size());
 
  706        auto& contacts = this->outContacts()->getData();
 
  707        mScan.exclusive(contactNum, true);
 
  708        contacts.resize(sum);
 
  712            cuExecute(deviceIds.size(),
 
  721        contactNumCpy.clear();
 
  724        nbr_cons_tmp.clear();
 
  727    DEFINE_CLASS(NeighborElementQuery);