World类

世界类的创建过程

world = new World(new Vector2(0, -120), true);

重力方向向下,所以为负数,是否可以睡眠,对于所有的动态刚体来说,当不发进行碰撞模拟的时候就进入睡眠状态。

在创建世界的过程中实际使用的代码为:

World world = new World(new Vec2(0,0));
world.setAllowSleep(flag);

对于world.setAllowSleep(flag);它会遍历所有的body,然后将其设置为flag,

扩展:

对于刚体创建出来,会放到世界刚体链表的头部,

new World(new Vec2(0,0));创建它会初始化实体,初始化动态树,还有成员变量的初始化。

  public World(Vec2 gravity, IWorldPool pool, BroadPhase broadPhase) {
    this.pool = pool;
    m_destructionListener = null;
    m_debugDraw = null;

    m_bodyList = null;
    m_jointList = null;

    m_bodyCount = 0;
    m_jointCount = 0;

    m_warmStarting = true;
    m_continuousPhysics = true;
    m_subStepping = false;
    m_stepComplete = true;

    m_allowSleep = true;
    m_gravity.set(gravity);

    m_flags = CLEAR_FORCES;

    m_inv_dt0 = 0f;

    m_contactManager = new ContactManager(this, broadPhase);
    m_profile = new Profile();

    m_particleSystem = new ParticleSystem(this);

    initializeRegisters();
  }

先理清思路,在对里面的作用分开说。

initializeRegisters()

使用那种方式创建图形
1.使用cir属性绘制圆
2.使用polygon绘制等
private void initializeRegisters() {
  addType(pool.getCircleContactStack(), ShapeType.CIRCLE, ShapeType.CIRCLE);
  addType(pool.getPolyCircleContactStack(), ShapeType.POLYGON, ShapeType.CIRCLE);
  addType(pool.getPolyContactStack(), ShapeType.POLYGON, ShapeType.POLYGON);
  addType(pool.getEdgeCircleContactStack(), ShapeType.EDGE, ShapeType.CIRCLE);
  addType(pool.getEdgePolyContactStack(), ShapeType.EDGE, ShapeType.POLYGON);
  addType(pool.getChainCircleContactStack(), ShapeType.CHAIN, ShapeType.CIRCLE);
  addType(pool.getChainPolyContactStack(), ShapeType.CHAIN, ShapeType.POLYGON);
}

他们各种组合都放起来。

private void addType(IDynamicStack<Contact> creator, ShapeType type1, ShapeType type2) {
  ContactRegister register = new ContactRegister();
  register.creator = creator;
  register.primary = true;
  contactStacks[type1.ordinal()][type2.ordinal()] = register;

  if (type1 != type2) {
    ContactRegister register2 = new ContactRegister();
    register2.creator = creator;
    register2.primary = false;
    contactStacks[type2.ordinal()][type1.ordinal()] = register2;
  }
}

后面在进行刚体范围比较的时候,会根据相应的图形来使用不同的检测方式。比如下面这个两个:

  • 第一个案例
final ContactRegister reg = contactStacks[type1.ordinal()][type2.ordinal()];
if (reg != null) {
  if (reg.primary) {
    Contact c = reg.creator.pop();
    c.init(fixtureA, indexA, fixtureB, indexB);
    return c;
  } else {
    Contact c = reg.creator.pop();
    c.init(fixtureB, indexB, fixtureA, indexA);
    return c;
  }
}
  • 第二个案例
  public void pushContact(Contact contact) {
    Fixture fixtureA = contact.getFixtureA();
    Fixture fixtureB = contact.getFixtureB();

    if (contact.m_manifold.pointCount > 0 && !fixtureA.isSensor() && !fixtureB.isSensor()) {
      fixtureA.getBody().setAwake(true);
      fixtureB.getBody().setAwake(true);
    }

    ShapeType type1 = fixtureA.getType();
    ShapeType type2 = fixtureB.getType();

    IDynamicStack<Contact> creator = contactStacks[type1.ordinal()][type2.ordinal()].creator;
    creator.push(contact);
  }

createBody

第一个创建类方法,使用它创建刚体,创建需要一个参数,BodyDef,它可以设置刚体的特性,它是运动的还是静态的。

userData = null;    //用户数据,比如创建一个地球,可以吧地球类存储在刚体里面
position = new Vec2();    //位置
angle = 0f;     //角度   后面改需要通过transform方法改
linearVelocity = new Vec2();  //线性速度
angularVelocity = 0f;   //角速度
linearDamping = 0f;  //线性阻尼
angularDamping = 0f;   //角速度阻尼
allowSleep = true;   //是不是运行睡眠 
awake = true;  //
fixedRotation = false;  //是不是运行自身转动,比如装了之后会翻转
bullet = false;  //子弹特性(慎用)
type = BodyType.STATIC;   //类型 
active = true;  //是不是活跃,不活跃将不会模拟   静态将不会模拟
gravityScale = 1.0f;   //重力缩放

刚体创建过程

 public Body(final BodyDef bd, World world) {
    assert (bd.position.isValid());
    assert (bd.linearVelocity.isValid());
    assert (bd.gravityScale >= 0.0f);
    assert (bd.angularDamping >= 0.0f);
    assert (bd.linearDamping >= 0.0f);

    m_flags = 0;

    if (bd.bullet) {
      m_flags |= e_bulletFlag;
    }
    if (bd.fixedRotation) {
      m_flags |= e_fixedRotationFlag;
    }
    if (bd.allowSleep) {
      m_flags |= e_autoSleepFlag;
    }
    if (bd.awake) {
      m_flags |= e_awakeFlag;
    }
    if (bd.active) {
      m_flags |= e_activeFlag;
    }

    m_world = world;
    //位置
    m_xf.p.set(bd.position);
    //角度
    m_xf.q.set(bd.angle);
    //中心
    m_sweep.localCenter.setZero();
    // 位置 (copy)
    m_sweep.c0.set(m_xf.p);
    m_sweep.c.set(m_xf.p);
    // 角度copy
    m_sweep.a0 = bd.angle;
    m_sweep.a = bd.angle;
    m_sweep.alpha0 = 0.0f;

    m_jointList = null;
    m_contactList = null;
    m_prev = null;
    m_next = null;

    m_linearVelocity.set(bd.linearVelocity);
    m_angularVelocity = bd.angularVelocity;

    m_linearDamping = bd.linearDamping;
    m_angularDamping = bd.angularDamping;
    m_gravityScale = bd.gravityScale;

    m_force.setZero();
    m_torque = 0.0f;

    m_sleepTime = 0.0f;

    m_type = bd.type;

    if (m_type == BodyType.DYNAMIC) {
      m_mass = 1f;
      m_invMass = 1f;
    } else {
      m_mass = 0f;
      m_invMass = 0f;
    }

    m_I = 0.0f;
    m_invI = 0.0f;

    m_userData = bd.userData;

    m_fixtureList = null;
    m_fixtureCount = 0;
  }

创建一个刚体就将里面的参数进行一次初始化。

创建夹具

FixtureDef属性:

shape = null;
userData = null;
friction = 0.2f;
restitution = 0f;
density = 0f;
filter = new Filter();
isSensor = false;

创建过程,从fixtureDef进行一次数据的复制

//值的一次复制
m_userData = def.userData;
m_friction = def.friction;
m_restitution = def.restitution;
m_body = body;
m_next = null;
m_filter.set(def.filter);
m_isSensor = def.isSensor;
m_shape = def.shape.clone();
// Reserve proxy space
//代理空间
int childCount = m_shape.getChildCount();
if (m_proxies == null) {
    m_proxies = new FixtureProxy[childCount];
    for (int i = 0; i < childCount; i++) {
        m_proxies[i] = new FixtureProxy();
        m_proxies[i].fixture = null;
        m_proxies[i].proxyId = BroadPhase.NULL_PROXY;
    }
}

if (m_proxies.length < childCount) {
    FixtureProxy[] old = m_proxies;
    int newLen = MathUtils.max(old.length * 2, childCount);
    m_proxies = new FixtureProxy[newLen];
    System.arraycopy(old, 0, m_proxies, 0, old.length);
    for (int i = 0; i < newLen; i++) {
        if (i >= old.length) {
            m_proxies[i] = new FixtureProxy();
        }
        m_proxies[i].fixture = null;
        m_proxies[i].proxyId = BroadPhase.NULL_PROXY;
    }
}
m_proxyCount = 0;
m_density = def.density;

Body中的create方法

  / * 创建之后  将其加入到树中间
   * 根据其 对质量进行重新计算
   */
  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;
  }

setTransform方法

重新设置位置和角度

public final void setTransform (b2Vec2 position, float angle) {
    assert (m_world.isLocked() == false);
    if (m_world.isLocked() == true) {
        return;
    }

    m_xf.q.set(angle);
    m_xf.p.set(position);

    // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter);
    b2Transform.mulToOutUnsafe(m_xf, m_sweep.localCenter, m_sweep.c);
    m_sweep.a = angle;

    m_sweep.c0.set(m_sweep.c);
    m_sweep.a0 = m_sweep.a;

    b2BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
    for (b2Fixture f : m_fixtureList) {
        f.synchronize(broadPhase, m_xf, m_xf);
    }
}

重新设置位置之后,就重新分配树的结构,以及lower和upper。

设置线速度 角速度 力

暂且认为是存储一个变量。

  • 线速度
public final void setLinearVelocity (b2Vec2 v) {
    if (m_type == b2BodyType.STATIC) {
        return;
    }

    if (b2Vec2.dot(v, v) > 0.0f) {
        setAwake(true);
    }

    m_linearVelocity.set(v);
}
  • 角速度
public final void setAngularVelocity (float w) {
    if (m_type == b2BodyType.STATIC) {
        return;
    }

    if (w * w > 0f) {
        setAwake(true);
    }

    m_angularVelocity = w;
}
public final void applyForce (b2Vec2 force, b2Vec2 point, boolean wake) {
    if (m_type != b2BodyType.DYNAMIC) {
        return;
    }

    if (isAwake() == false) {
        setAwake(true);
    }

    // m_force.addLocal(force);
    // Vec2 temp = tltemp.get();
    // temp.set(point).subLocal(m_sweep.c);
    // m_torque += Vec2.cross(temp, force);

    m_force.x += force.x;
    m_force.y += force.y;
    // m_sweep就是它的位置
    m_torque += (point.x - m_sweep.c.x) * force.y - (point.y - m_sweep.c.y) * force.x;
}
//力不在中心就会有一个旋转

在中心加力 就不会有扭转力

public final void applyForceToCenter (b2Vec2 force, boolean wake) {
    if (m_type != b2BodyType.DYNAMIC) {
        return;
    }

    if (isAwake() == false) {
        setAwake(true);
    }

    m_force.x += force.x;
    m_force.y += force.y;
}

为什么设置了就设置睡眠,可能是因为位置发生变化,已经没啥用了, 设置不活跃,下次模拟的时候在进行模拟。

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

推荐阅读更多精彩内容

  • 初始化box2d 这篇应该是box2d的一个整体的说明,它有哪些功能,还有一些总体的概括。 参数 积分步 Box2...
    大旺旺的弟弟小旺旺阅读 651评论 0 1
  • 一.刚体组件的属性介绍 刚体能让你的游戏对象被物理引擎所控制,它能通过受到推力和扭力来实现真实的物理表现效果。所有...
    沉麟阅读 1,308评论 0 0
  • 上一讲看到了刚体属性,以及刚体的形状和创建过程,可以做自由下落,最后知道怎样显示出视图。这一节完成一些特殊的效果。...
    大旺旺的弟弟小旺旺阅读 1,205评论 0 0
  • 教练( oussama himani kha TiB ):好的。我们开始吧。欢迎来到机器人2008年。新年快乐,每...
    疯霜阅读 297评论 0 0
  • 一、基础概念 参考拉小登博客 初识Box2D关节b2Joint 1.刚体rigidbody :刚体是指在运动中和受...
    合肥黑阅读 4,105评论 0 1