Box2D中切割刚体效果的实现一览(二)
我们继续来实现切割效果。
我们现在有了切割线和多边形,可以利用Box2d的射线投射(RayCast)来检测切割线和多边形的交点(入射点)。在Box2d中通过定义b2RayCastCallback的子类来获取射线投射的结果,关于Box2d中的射线投射的使用,可以参考Box2Dv2.3.0 用户指南(第十章)。
我们创建b2RayCastCallback的子类MyRayCastCallback,声明如下:
#import"Box2D.h"
classMyRayCastCallback : public b2RayCastCallback {
public:
NSMutableArray* results;
NSMutableArray* endResults;
BOOL resultFlag;
MyRayCastCallback();
float32 ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2&normal, float32 fraction);
void ClearResults();
void ResetFlag();
};
成员中定义了两个数组成员,results和endResults,原因是Box2d中射线投射得到的是线段射入多边形的第一个入射点,而实际上我们需要两个切点,因此我们的思路是做两次射线投射,第一次从lineStartSave到lineEndSave,第二次相反。从而得到两组入射点,分别记录在results和endResults两个数组中。
resultFlag用来区分两次投射。方法ResetFlag用于反置resultFlag。ClearResults方法用来清空投射结果。ReportFixture方法用来记录投射结果。
接着我们定义一个类RayCastResult来表示每一个投射的结果,声明如下:
#import"Box2D.h"
@interfaceRayCastResult : NSObject
-(id)initWithFixture:(b2Fixture*)fixture
point:(b2Vec2) point
normal:(b2Vec2) normal
fraction:(float32) fraction;
@propertyb2Fixture* fixture;
@propertyb2Vec2 point;
@propertyb2Vec2 normal;
@propertyfloat32 fraction;
@end
类中定义了4个属性,分别对应投射得到的装置,入射点,法线和比例系数。
类的定义(实现)如下:
#import"RayCastResult.h"
@implementationRayCastResult
@synthesizefixture;
@synthesizepoint;
@synthesizenormal;
@synthesizefraction;
-(id)initWithFixture:(b2Fixture*)fixt point:(b2Vec2)p normal:(b2Vec2)n fraction:(float32)f {
if (self = [super init]) {
self.fixture = fixt;
self.point = p;
self.normal = n;
self.fraction = f;
}
return self;
}
@end
没有太多需要说明的,定义了一个构造函数用来初始化所有属性。
接着我们来看MyRayCastCallback类的定义:
#import"MyRayCastCallback.h"
#import"RayCastResult.h"
MyRayCastCallback::MyRayCastCallback(){
results = [[NSMutableArray alloc] init];
endResults = [[NSMutableArray alloc] init];
resultFlag = true;
}
float32MyRayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &point,const b2Vec2 &normal, float32 fraction) {
if (resultFlag) {
[results addObject:[[RayCastResult alloc] initWithFixture:fixture point:pointnormal:normal fraction:fraction]];
} else {
[endResults addObject:[[RayCastResult alloc] initWithFixture:fixturepoint:point normal:normal fraction:fraction]];
}
return 1;
}
voidMyRayCastCallback::ClearResults() {
[results removeAllObjects];
[endResults removeAllObjects];
}
voidMyRayCastCallback::ResetFlag() {
resultFlag = !resultFlag;
}
ReportFixture方法中通过对resultFlag的判断来确定结果应该存放到results中还是endResults中,方法返回1,这样当切割线跨过多个多边形的时候,能够捕获到所有的切点。其他的方法没有太多复杂的逻辑,不做说明了。
接着我们在HelloWorldLayer中添加一个成员:
MyRayCastCallbackrayCastCallback;
然后定义下面的方法来表示一次RayCast的执行:
-(void)doRayCast{
rayCastCallback.ClearResults();
world->RayCast(&rayCastCallback, [self toVec:lineStartSave], [selftoVec:lineEndSave]);
rayCastCallback.ResetFlag();
world->RayCast(&rayCastCallback, [self toVec:lineEndSave], [selftoVec:lineStartSave]);
rayCastCallback.ResetFlag();
}
首先清空结果,然后执行第一次RayCast,反置resultFlag,然后执行第二次RayCast得到反向的切点,再次反置resultFlag。执行完这个方法后,所有的切点都储存在rayCastCallback的results和endResults中了。
正常情况下,我们希望在每次拖拽出切割线并松开后来执行射线投射的计算,因此应该在ccTouchEnded方法中添加doRayCast的调用。但是这里我们希望更加直观地看到切点的效果,所以我们在ccTouchMoved方法中添加调用,这样当切割线随着触点的移动,会实时地计算所有切点。接着我们在draw方法中添加下面的代码,在每个切点上绘制一个圆形来直观地表现其位置:
if([rayCastCallback.results count] > 0) {
for (RayCastResult* result in rayCastCallback.results) {
CGPoint point = [self toCGPoint:result.point];
ccDrawCircle(point, 3, 0, 10, YES);
}
ccDrawColor4F(255, 0, 0, 255);
for (RayCastResult* result in rayCastCallback.endResults) {
CGPoint point = [self toCGPoint:result.point];
ccDrawCircle(point, 3, 0, 10, YES);
}
}
这里正向和反向投射得到的切点我们用不同的颜色来绘制,反向的切点用红色(255,0,0),正向的用白色。使用ccDrawCircle方法来绘制圆形。
由于Box2d中使用的长度单位不是像素,因此我们实现了两个b2Vec2和CGPoint之间转换的函数来方便调用:
-(b2Vec2)toVec:(CGPoint)p {
b2Vec2 result(p.x / (float32)PTM_RATIO, p.y / (float32)PTM_RATIO);
return result;
}
-(CGPoint)toCGPoint:(b2Vec2)vec {
return CGPointMake(vec.x * (float32)PTM_RATIO, vec.y * (float32)PTM_RATIO);
}
实现后得到的运行效果(我们添加了3个多边形):
先到这里,最后一篇中我们来完成刚体的切割效果的制作。
Box2D中切割刚体效果的实现一览(二)相关推荐
- Box2d中使用b2Separate开源代码创建凹多边形及其算法分析
我们知道,在Box2d中默认只能创建凸多边形,如果我们定义的顶点不小心形成了一个凹多边形,那么凹面部分的法线会存在问题,并且在物理模拟的时候会有问题(比如检测不到碰撞等等). 要想直接创建凹多边 ...
- Box2d学习笔记三:box2d中几个重要的类
我们已经知道box2d中的唯一物种:刚体,然而仅仅一个刚体对象并不能完成相应的物理模拟.如果看过box2d的帮助文档就知道,b2Body中提供的函数和属性中,并没有我们需要的物理属性,可以回忆一下,我 ...
- ae破碎效果在哪_怎么用AE做切割破碎效果的影视动画
1.打开软件AE,新建一个合成,命名为[切割破碎效果]. 2.用[椭圆工具]绘制一个正圆,调整大小为388,并命名为圆. 3.选择[多边形工具]绘制一个三角形,显示标尺去精确调整大小和角度. 4.在圆 ...
- 气泡图在开源监控工具中的应用效果
气泡图在开源监控工具中的应用 Bubble Chart(气泡图),使用气泡图便于在行.列两个方向同时进行比较.气泡图也清晰地告诉哪里大.哪里小.如图1~图5为你展示几款开源监控工具在使用气泡图时的应用 ...
- Android关于绘图中Shader 的效果(中级)
Android关于绘图中Shader 的效果(中级) 关于绘图中Shader 的效果 本人对API中Shaser的参数理解不够深刻 所以只能测试来看 效果一下就看出来了 Shader mShade=n ...
- DevExpress中透明玻璃效果
Aero玻璃效果 下图左是DevExpress无玻璃效果,图右是Windows自带玻璃效果. Windows Aero 是从 Windows Vista 开始使用的新型用户界面,透明玻璃感让用户一眼贯 ...
- 网络营销专员浅析如何判断网络营销中网站优化效果几何?
对于新老站长来说在网站网络营销推广过程中时常都会针对行业内类似同行网站进行网站优化效果分析,并针对其他网站重点优势取长补短以此来提升自家网站优化水平,大大提升企业网站在搜索引擎中的网站排名和权重指数. ...
- tableau实战系列(三十四)-教你如何在tableau中实现3D效果作图
前言 我们知道,目前 Tableau 还不支持 3D 图表的实现.但是,如果你希望在 Tableau 中呈现立体效果,我们可以另辟蹊径,来实现一些简单的. 柱形图很常见,因为是平面的,也被称为条形图. ...
- matlab中给图像加几个矩形框_没想到!PPT中的这个效果,用好了,简直就是渣图美化器...
相信大家一定看到过,透过磨砂玻璃呈现在眼前的景色,是不是有种朦胧美? 其实,在PPT中你也可以复刻出这样的效果.例如,这样的PPT页面: 把背景虚化掉,更加突出主题. 你想知道PPT中的磨砂效果,都是 ...
最新文章
- 清华大学:2021元宇宙发展研究报告
- 3大主流前端框架对比
- 数据库的简单操作命令
- 当物联网系统出现故障:使用低质量物联网数据的风险
- 设计一个可扩展的用户登录系统
- 《Java程序设计》第2周学习总结
- 201771010101 白玛次仁 《2018面向对象程序设计(Java)》第十三周学习总结
- oracle下定时删除归档脚本
- ubuntu python3 mysql_ubuntu14.04 python3.*连接mysql
- 学了这么久的Redis,竟然还不知道事务
- 数据分析没价值?——深思对业务的洞察有多少?
- maya python 游戏与影视编程指南_Maya Python游戏与影视编程指南
- 谷歌浏览器设置定位_谷歌浏览器手动设置位置信息
- 不做生活上的“富察皇后”,Soul星球遇见真实的灵魂
- 在线CUR格式转换器
- Java快递配送管理系统
- openssl 加密解密 指令_openssl命令aes加密和解密
- layui 表格加载动画_巴州动画
- gamemaker学习笔记:打包Android过程记录
- 软件使用说明网站+IT新闻评论
热门文章
- 【前端实例代码】如何使用 HTML 和 CSS 快速创建一个响应式导航栏
- 安规测试简介(二)-常见安规认证测试之CE认证
- VS2017 + Qt 设置窗口置顶与取消置顶
- 计算机考试为什么试题不能复制,3月ACCA考试开场——ACCA机考复制粘贴究竟可不可以?...
- BJDCTF 2nd- -开场曲
- cesium实现开场动画效果
- android-护士站管理系统
- 解决windows10网络数据使用量不统计问题以及任务管理器网络数据为0Mbps问题
- 俄乌局势再起波澜,3月季节性一览,甲醇认购大涨,CCS05收官LPP季节性下跌2022.2.28
- Python 洛谷 p1104 生日