embox2d-helpers.js

//Having to type 'Box2D.' in front of everything makes porting
//existing C++ code a pain in the butt. This function can be used
//to make everything in the Box2D namespace available without
//needing to do that.
function using(ns, pattern) {    
    if (pattern == undefined) {
        // import all
        for (var name in ns) {
            this[name] = ns[name];
        }
    } else {
        if (typeof(pattern) == 'string') {
            pattern = new RegExp(pattern);
        }
        // import only stuff matching given pattern
        for (var name in ns) {
            if (name.match(pattern)) {
                this[name] = ns[name];
            }
        }       
    }
}


//to replace original C++ operator =
function copyVec2(vec) {
    return new Box2D.b2Vec2(vec.get_x(), vec.get_y());
}

//to replace original C++ operator * (float)
function scaleVec2(vec, scale) {
    vec.set_x( scale * vec.get_x() );
    vec.set_y( scale * vec.get_y() );            
}

//to replace original C++ operator *= (float)
function scaledVec2(vec, scale) {
    return new Box2D.b2Vec2(scale * vec.get_x(), scale * vec.get_y());
}


// http://stackoverflow.com/questions/12792486/emscripten-bindings-how-to-create-an-accessible-c-c-array-from-javascript
function createChainShape(vertices, closedLoop) {
    var shape = new Box2D.b2ChainShape();            
    var buffer = Box2D.allocate(vertices.length * 8, 'float', Box2D.ALLOC_STACK);
    var offset = 0;
    for (var i=0;i<vertices.length;i++) {
        Box2D.setValue(buffer+(offset), vertices[i].get_x(), 'float'); // x
        Box2D.setValue(buffer+(offset+4), vertices[i].get_y(), 'float'); // y
        offset += 8;
    }            
    var ptr_wrapped = Box2D.wrapPointer(buffer, Box2D.b2Vec2);
    if ( closedLoop )
        shape.CreateLoop(ptr_wrapped, vertices.length);
    else
        shape.CreateChain(ptr_wrapped, vertices.length);
    return shape;
}

function createPolygonShape(vertices) {
    var shape = new Box2D.b2PolygonShape();            
    var buffer = Box2D.allocate(vertices.length * 8, 'float', Box2D.ALLOC_STACK);
    var offset = 0;
    for (var i=0;i<vertices.length;i++) {
        Box2D.setValue(buffer+(offset), vertices[i].get_x(), 'float'); // x
        Box2D.setValue(buffer+(offset+4), vertices[i].get_y(), 'float'); // y
        offset += 8;
    }            
    var ptr_wrapped = Box2D.wrapPointer(buffer, Box2D.b2Vec2);
    shape.Set(ptr_wrapped, vertices.length);
    return shape;
}

function createRandomPolygonShape(radius) {
    var numVerts = 3.5 + Math.random() * 5;
    numVerts = numVerts | 0;
    var verts = [];
    for (var i = 0; i < numVerts; i++) {
        var angle = i / numVerts * 360.0 * 0.0174532925199432957;
        verts.push( new b2Vec2( radius * Math.sin(angle), radius * -Math.cos(angle) ) );
    }            
    return createPolygonShape(verts);
}

function getPointsByPolygonShape(fixture) {
    var shape = fixture.GetShape();
    var body = fixture.GetBody();
    var polyShape = Box2D.castObject( shape, Box2D.b2PolygonShape );
    if (polyShape == null) {
        return [];
    }
    var count = polyShape.GetVertexCount();
    var ret = [];
    for (var i = 0; i < count; i++) {
        var p = polyShape.GetVertex(i);
        var pWorld = body.GetWorldPoint(p);
        ret.push(new Vertex(pWorld.get_x(), pWorld.get_y()));
    } 
    return ret;
}

function getPointsByPolygonBody(body) {
    var ptr = body.GetFixtureList();
    var arr = [];
    while(ptr.e != 0) {
        var vertices = getPointsByPolygonShape(ptr);
        ptr = ptr.GetNext();
        arr.push(vertices);
    }

    // var ret = mergeTwoSets(arr[0], arr[1]);
    // for (var i = 2; i < arr.length; i++) {
    //     ret = mergeTwoSets(ret, arr[i]);
    // }
    var first = arr.shift();
    while (arr.length > 0) {
        var i=0;
        var merged = false;
        for (; i < arr.length; i++) {
            var beMerge = copyArr(arr[i])
            var set = mergeTwoSets(first, beMerge);
            if (set != null) {
                first = set;
                merged = true;
                break;
            }
        }
        arr.splice(i, 1);
        if (!merged) {
            break;
        }
    }
    return first;
}

function mergeTwoSets(arr1, arr2) {
    var a1, a2, b1, b2;
    a1 = b2 = a2 = b1 = -1;
    for (var i = 0; i < arr1.length; i++) {
        var a = arr1[i];
        for (var j = 0; j < arr2.length; j++) {
            var b = arr2[j];
            if (a.equals(b)) {
                a1 = i;
                a2 = i+1 >= arr1.length ? 0 : i+1;
                b1 = j==0 ? arr2.length-1 : j-1;
                b2 = j;
                break;
            }
        }
        if (a1 >= 0) {
            break;
        }
    }
    if (a1 < 0 || !arr1[a1].equals(arr2[b2]) || !arr1[a2].equals(arr2[b1])) {
        return null;
    }
    for (var i = 0; i < b1; i++) {
        arr2.push(arr2.shift());
    }
    arr2.splice(0, 2);
    if (a2 == 0) {
        return arr1.concat(arr2);
    } else {
        var arr3 = arr1.splice(a2, arr1.length-a2);
        return arr1.concat(arr2).concat(arr3);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值