Box2d源码分析(刚体)

概述中知道了什么是世界,如何模拟世界重力,以及时间步和另外两个参数的使用,以及意义。世界的存在,有了物体才可以更加的完美。
刚体就是世界中的物体,可以仿真各种物体,对世界中物体的操作基本 就是对刚体的操作。
1.刚体定义
2.创建并加入到世界中
3.刚体的形状
4.显示出刚体的调试视图

刚体

a rigid Body,一般的看到的万物的形状都可以看作是刚体,刚体也是学习的核心,可以用来模拟所有的物体,它可以模拟出碰撞、反弹、运动轨迹等各种物体现象模拟和数据都是基于刚体实现的,所以属性比较多,位置、速度、质量、反弹系数等。

创建刚体

创建刚体,不仅仅是创建一个刚体,还需要创建bodyDef和fixtureDef,共同创建出来。

  • b2BodyDef:创建需要的信息
  • b2Body:创建刚体
  • b2FixtureDef:创建刚体的信息。
    对于刚体来说,包含的信息比较多以及自身的特性,所以需要创建一个b2BodyDef和b2FixtureDef。所以需要创建这两个,并成功的设置相关的属性。


    image.png

    image.png

    上面只是刚体自身属性和外部属性,我们仍然使用Body来创建。
    创建代码

BodyDef bodyDef = new BodyDef();
bodyDef.type = this.type;
bodyDef.position.set(getX(Align.center),getY(Align.center));
this.body = Constant.world.createBody(bodyDef);
if (shape == null){
   PolygonShape polygonShape = new PolygonShape();
   polygonShape.setAsBox(getWidth()/2 , getHeight()/2);
   shape = polygonShape;
}
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
if (categoryBits != -1){
  fixtureDef.filter.categoryBits = categoryBits;
}
if (maskBits != -1) {
     fixtureDef.filter.maskBits = (short) maskBits;
}
fixtureDef.density = 100;
body.createFixture(fixtureDef);
shape.dispose();
body.setUserData(this);

源码分析世界创建body的过程。

long bodyAddr = 
        jniCreateBody(addr, 
                            def.type.getValue(),
                            def.position.x, 
                            def.position.y, 
                            def.angle, 
                            def.linearVelocity.x,
                            def.linearVelocity.y, 
                            def.angularVelocity, 
                            def.linearDamping, 
                            def.angularDamping, 
                            def.allowSleep, 
                            def.awake,
                            def.fixedRotation, 
                            def.bullet, 
                            def.active, 
                            def.gravityScale);
Body body = freeBodies.obtain();
body.reset(bodyAddr);
this.bodies.put(body.addr, body);
return body;

reset方法

protected void reset (long addr) {
    this.addr = addr;
    this.userData = null;
    for (int i = 0; i < fixtures.size; i++)
            this.world.freeFixtures.free(fixtures.get(i));
            fixtures.clear();
            this.joints.clear();
    }
}

创建body,body有fixturedef和joints以及userData.;将他们清掉。
这个创建和c++创建有一些区别,等下面补充的时候在加。

夹具

fixture的使用,夹具是一个固定设施,用来定义一些属性,材料本身的特性,比如摩擦力、密度、质量等。它可以设置刚体的形状,如果没有形状是不可以进行碰撞模拟的。
一般的常见图形有园和矩形,还有一些简单的 。对于fixtureDef只是短暂停的存储,它里面有属性fixture,我没让你创建的时候也是将数据在复制到fixture。并且fixtrue必须依附在刚体上才可以有作用,比如你的躯体脱离了你这个人,只是一个行尸走肉,并没有什么用户,一个刚体可以包含不止一个。
比如一个人,头部的硬度和肚子的硬度反弹系数不同,我们就需要创建两个。也就说刚体创建之后可以对其在增加fixture,实现形状的组合

FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = shape;
        if (categoryBits != -1){
            fixtureDef.filter.categoryBits = categoryBits;
        }
        if (maskBits != -1) {
            fixtureDef.filter.maskBits = (short) maskBits;
        }
        fixtureDef.density = 100;
        body.createFixture(fixtureDef);
      

源码实现

 public final Fixture createFixture(FixtureDef def) {
    assert (m_world.isLocked() == false);

    if (m_world.isLocked() == true) {
      return null;
    }

    Fixture fixture = new Fixture();
    fixture.create(this, def);

    if ((m_flags & e_activeFlag) == e_activeFlag) {
      BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
      fixture.createProxies(broadPhase, m_xf);
    }

    fixture.m_next = m_fixtureList;
    m_fixtureList = fixture;
    ++m_fixtureCount;

    fixture.m_body = this;

    // Adjust mass properties if needed.
    if (fixture.m_density > 0.0f) {
      resetMassData();
    }

    // Let the world know we have a new fixture. This will cause new contacts
    // to be created at the beginning of the next time step.
    m_world.m_flags |= World.NEW_FIXTURE;

    return fixture;
  }

创建一个 fixture,然后将创建好的fixtureDef传入 进行初始化,然后将其加入到清单中,最后将fixture设置给body对象,将fixture回传。这个时候图形就没有什么作用了,可以进行清楚操作。

如何理解bodydef和fixturedef

BodyDef:在创建之前将刚体的属性准备好, 创建的时候将属性值传递给内部的私有属性。数据传递之后,他就没有啥用处了,可以继续使用,重新修改,让下一个继续使用。所以无法使用bodydef来修改属性。需要修改可以通过下面的方法

body.setActive(xxx);
body.getTransform().setPosition();
image.png

bodyDef对应body中的属性修改。对于fixture也是一样的。


image.png

我们创建之后需要可以使用上面的方法对属性进行修改。

形状

刚体的形状,在世界模拟中,根据形状进行碰撞模拟。我们也了解到刚体的形状可以根据多个fixture进行组合而成,也就是说它们可以加入多个fixture.

圆形

圆形创建就很简单了,只有一个参数半径就可以了,默认值是0,这里创建的单位都是米,他和像素的转换关系为 30px = 1m;将创建的图形传给你夹具就是我们创建出刚体的形状。

矩形

创建矩形可以使用PolygonShape创建它是一个多边形的类,他没有什么构造函数,但是可以调用相应的函数来返回相应的形状。,比如矩形可使用setAsBox创建。
sexAsBox的使用以刚体的中心坐标位置为中心点的矩形,及就是宽和高都是i相对于刚体坐标位置对称的,需要传入两个参数宽和高。这里是半宽实际的宽和高是传入的二倍。并且像素和宽高的对应关系
需要进行转换,比如创建一个60x100的矩形,需要传入的参数是30/30 50/30;

回顾一下

创建def,创建body,创建fixture 创建图形 添加fixture.

看到效果

打开调试视图,box2d是一个引擎,我们并不可以看到,需要我们打开调试试图,否则就一无所有。
我们可以使用step进行模拟,在模拟之后调用调试视图得到显示的状态

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容