在physx中创建射线ray,并获取碰撞点

通过raycastSingle函数去获取发射的射线是否会碰到物体,不需要特殊处理的可以不使用回调。

不用回调的版本

// origin是起点, unitDir是方向
int RayCaseSingle(PxVec3 &origin, PxVec3 &unitDir)
{PxRaycastHit hitInfo; // 返回的点,法向量信息等都在这里PxReal maxDist = FLT_MAX; // 最大射线距离//PxHitFlag::eMESH_ANY //返回任一次的射线与mesh的交互,因为是raycaseSingle,设不设置这个无所谓// 获取点, 法向量,还有UV信息PxHitFlags hitFlags = PxHitFlag::ePOSITION | PxHitFlag::eNORMAL | PxHitFlag::eUV ;bool isRayHit = PxSceneQueryExt::raycastSingle(*gScene,origin,unitDir,maxDist,hitFlags,hitInfo);if (isRayHit) {cout << "=====hitInfo.x: " << hitInfo.position.x << " y: " << hitInfo.position.y << " z: " << hitInfo.position.z << endl;PxVec3 pose = actor->getGlobalPose().p;cout << "actor x:" << pose.x << " y:" << pose.y << " z:" << pose.z << endl;}elsecout << "rayHit is not hit" << endl;return isRayHit;
}

带回调版本的射线

因为我设置的是从物体的身体里面发射出来的,所以我需要特殊处理一下,将该物体过滤一下,让这个物体对于射线而言是一个忽略状态。

  • 设置一个用于全局过滤的变量
const PxFilterData collisionGroupIgnore(0, 0, 0, 1); // 用于忽略物体,内容自定义
  • 下面是回调配置
class  PxSenceRayCallback : public PxSceneQueryFilterCallback
{public:virtual PxQueryHitType::Enum preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags) override{cout << "hit preFilter" << endl;if (shape->getSimulationFilterData() == collisionGroupIgnore){cout << "ignore data" << endl;return PxQueryHitType::Enum::eNONE; //should ignore this shape}return PxQueryHitType::Enum::eBLOCK;//eNONE   //should ignore this shape//eTOUCH // 要使用这个要有缓冲区//eBLOCK // 射线发出有hit需要返回用这个}virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit) override{cout << "hit postFilter" << endl;return PxQueryHitType::Enum::eBLOCK;}};PxSenceRayCallback gSenceRay;
  • 下面是封装好的调用api
bool GetShapeSimulationFilterData(PxRigidActor *actor, PxFilterData &filterdata)
{const PxU32 numShapes = actor->getNbShapes();if (numShapes <= 0) {return false;}PxShape* shapes = NULL;actor->getShapes(&shapes, 1);filterdata = shapes->getSimulationFilterData();return true;
}bool SetShapeSimulationFilterData(PxRigidActor *actor, const PxFilterData &filterdata)
{const PxU32 numShapes = actor->getNbShapes();if (numShapes <= 0) {return false;}PxShape* shapes = NULL;actor->getShapes(&shapes, 1);shapes->setSimulationFilterData(filterdata);PxFilterData oldFilterdata = shapes->getSimulationFilterData();return true;
}
// 此处使用actor进行传入是为了测试方便
int RayCaseSingle(PxRigidActor * actor, PxVec3 &unitDir)
{PxVec3 origin = actor->getGlobalPose().p ;PxRaycastHit hitInfo; // 返回的点,法向量信息等都在这里PxReal maxDist = FLT_MAX; // 最大射线距离PxU32 maxHits = 1; // 返回的最多命中个数//PxHitFlag::eMESH_ANY //返回任一次的射线与mesh的交互,因为是raycaseSingle,设不设置这个无所谓// 获取点, 法向量,还有UV信息PxHitFlags hitFlags = PxHitFlag::ePOSITION | PxHitFlag::eNORMAL | PxHitFlag::eUV ;PxQueryFilterData filterdata = PxQueryFilterData();// 因为我是从actor的中心发出的射线,会碰到自身的actor,使用回调忽略掉自身的actorfilterdata.flags |= PxQueryFlag::ePREFILTER; // 设置回调信息,可以用作特殊处理// 获取之前的filterdata暂存一下PxFilterData oldFilterdata;GetShapeSimulationFilterData(actor, oldFilterdata);// 设置碰撞忽略SetShapeSimulationFilterData(actor, collisionGroupIgnore);bool isRayHit = PxSceneQueryExt::raycastSingle(*gScene,origin,unitDir,maxDist,hitFlags,hitInfo,filterdata,&gSenceRay);if (isRayHit) {cout << "=====hitInfo.x: " << hitInfo.position.x << " y: " << hitInfo.position.y << " z: " << hitInfo.position.z << endl;PxVec3 pose = actor->getGlobalPose().p;cout << "actor x:" << pose.x << " y:" << pose.y << " z:" << pose.z << endl;}elsecout << "rayHit is not hit" << endl;// 还原回来SetShapeSimulationFilterData(actor, oldFilterdata);return isRayHit;
}

有个小坑!!!!!

有个小坑!!!!!

shape这个变量是一个坑,为什么这么说呢? 它使用下面这个接口创建的时候,不能使用setSimulationFilterData这个函数!!!!!!!!!!!!!!!!!!这个函数在过滤的时候,非常重要。 不过呢,使用userdata定义自己的结构代替也可以。

PX_FORCE_INLINE PxShape* PxPhysics::createShape  (   const PxGeometry &  geometry,
const PxMaterial &  material,
bool    isExclusive = false,
PxShapeFlags    shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE
)

如果之前创建刚体是用的这种方法,那么setSimulationFilterData就会无法调用,会提示警告。
shared shapes attached to actors are not writable.

void createBody(const PxTransform& t, PxGeometry& geometry)
{PxShape* shape = NULL;// 创建出形状 shape = gPhysics->createShape(geometry, *gMaterial);PxRigidDynamic* dynamic = gPhysics->createRigidDynamic(t);dynamic->attachShape(*shape);PxRigidBodyExt::updateMassAndInertia(*dynamic, 10.0f);// 场景中添加演员gScene->addActor(*dynamic);shape->release();
}

需要使用setSimulationFilterData接口的话,请使用下面的方法创建

void createBody(const PxTransform& t, PxGeometry& geometry)
{// 最后一个参数也就是使用 PxRigidBodyExt::updateMassAndInertia(*dynamic, 10.0f);设置的第二个参数PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);// 场景中添加演员gScene->addActor(*dynamic);shape->release();
}

如果想要使用回调进行过滤,又无法使用setSimulationFilterData接口的情况下,在shape变量中有userdata指针,可以通过给他定义自己想要的结构或者数据, 然后在回调里面调用shape指针,判断使用自己设置好的userdata即可。

在physx中创建射线ray,并获取碰撞点相关推荐

  1. 在physx中创建射线raycase,并获取碰撞点

    给物体创建射线ray 通过raycastSingle函数去获取发射的射线是否会碰到物体,不需要特殊处理的可以不使用回调. 不用回调的版本 // origin是起点, unitDir是方向 int Ra ...

  2. java插件获取首选项_Eclipse RCP 中创建自定义首选项,并能读取首选项中的值

    Eclipse RCP的插件中若想自己定义首选项需要扩展扩展点: org.eclipse.core.runtime.preferences //该扩展点用于初始化首选项中的值 org.eclipse. ...

  3. java 获取对象方法有哪些方法有哪些方法有哪些_Java中创建String 对象的方法有哪些...

    Java中创建String 对象的方法有哪些 发布时间:2020-11-25 16:45:30 来源:亿速云 阅读:71 作者:Leah 这篇文章将为大家详细讲解有关Java中创建String 对象的 ...

  4. Java 文件操作二(重命名、设置只读、是否存在、指定目录中创建文件、获取文件修改日期、创建文件、文件路径比较)

    文件重命名 import java.io.File;public class Main {public static void main(String[] args) {File oldName = ...

  5. git拉取远程分支并创建本地分支和Git中从远程的分支获取最新的版本到本地

    git拉取远程分支并创建本地分支 一.查看远程分支 使用如下Git命令查看所有远程分支: git branch -r 二.拉取远程分支并创建本地分支 方法一 使用如下命令: git checkout ...

  6. c# 获取word表格中的内容_Java 在Word中创建嵌套表格

    嵌套表格,即在一个大的表格单元格中再嵌进去一个或几个小的表格,使表格内容布局合理.本文将通过java程序来演示如何在Word中创建嵌套表格. 使用工具:Free Spire.Doc for Java ...

  7. Unity 3D中的射线与碰撞检测

    创建一条射线Ray需要指明射线的起点(origin)和射线的方向(direction).这两个参数也是Ray的成员变量.注意,射线的方向在设置时如果未单位化,Unity 3D会自动进行单位归一化处理. ...

  8. Unity 3D中的射线与碰撞检测 1

    创建一条射线Ray需要指明射线的起点(origin)和射线的方向(direction).这两个参数也是Ray的成员变量.注意,射线的方向在设置时如果未单位化,Unity 3D会自动进行单位归一化处理. ...

  9. Unity3D客户端在游戏场景中创建阻挡并用二进制导出

    在公司的项目中给策划做了一个可以在场景中创建简单阻挡物体的小工具,也许大家有用的到的,拿出来分享一下. 整体思路是把地形用一米见方的格子分隔,然后在格子里放置cube代替阻挡,存盘时用一维数组,1表示 ...

最新文章

  1. 将base64编码图片上传到七牛云
  2. 超过Google,微信AI在NLP领域又获一项世界第一
  3. hashmap的五种便利方式
  4. C# List 嵌套学习总结
  5. 微服务配置中心是干啥的_微服务入门到精通-分布式配置中心(续)
  6. linux 中使用 crontab 执行定时任务
  7. android手机拍摄权限,react-native 手机拍照权限
  8. nmap入门之主机发现
  9. iOS开发-CocoaPods使用详细说明
  10. python中英文字频率_python统计文本字符串里单词出现频率的方法
  11. Git子模块头#39;引用不是树#39;错误
  12. 【数据结构笔记03】算法实例:最大子列和
  13. 战舰少女服务器不显示,战舰少女进不去 闪退及连接不上解决方法
  14. android滚动视图实例,android实现自定义滚动条
  15. 智慧交通规划设计方案解析
  16. FPGA verilog 临近插值任意比例视频缩放代码
  17. html chm用浏览器打开方式,如何在网页中打开chm格式的文件
  18. [绍棠] This In-App purchase has already been bought. It will be restored for free.
  19. 怎样分析数据致提高产出?(一)
  20. 未来IT人才市场最热门的12项技能

热门文章

  1. 以俄语为母语或官方语言的地区
  2. 量化投资——IC、IR、RankIC
  3. FreeRTOS给予裸机编程的思考
  4. android LinearGradient和RadialGradient
  5. ‘SchemaItem‘ object, such as a ‘Column‘ or a ‘Constraint‘ expected, go <class ‘int‘>
  6. 第一次世界大战是因为昆虫引起
  7. 技术指南 | 如何集成Perforce版本控制系统Helix Core (P4V) 与软件生命周期管理工具Helix ALM
  8. WebStorm添加px转rem单位插件
  9. win10系统cmd运行exe文件
  10. Windows10环境下Python 开发环境搭建