Android基于LiquidFun引擎实现软体碰撞效果

一、实现效果

Android使用LiquidFun物理引擎实现果冻碰撞效果

二、Android代码

    // 加载liquidfun动态库
    static {
        System.loadLibrary("liquidfun");
        System.loadLibrary("liquidfun_jni");
    }

    class ParticleData {
        long id;
        ParticleSystem particleSystem;
        float particleRadius;
        int textureId;
        ArrayList<ArrayList<Integer>> row;

        public ParticleData(long id, ParticleSystem ps, float particleRadius, ArrayList<ArrayList<Integer>> row, int textureId) {
            this.id = id;
            this.particleSystem = ps;
            this.textureId = textureId;
            this.particleRadius = particleRadius;
            this.row = row;
        }

        public long getId() {
            return this.id;
        }

        public ParticleSystem getParticleSystem() {
            return this.particleSystem;
        }

        public int getTextureId() { return this.textureId;}

        public float getParticleRadius() { return this.particleRadius;}

        public ArrayList<ArrayList<Integer>> getRow() { return this.row;}
    }

    class BodyData {
        long id;
        Body body;
        FloatBuffer vertexBuffer;
        FloatBuffer uvBuffer;
        int vertexLen;
        int drawMode;
        int textureId;

        public BodyData(long id, Body body, float[] buffer, float[] uv, int drawMode, int textureId) {
            this.id = id;
            this.body = body;
            this.vertexBuffer = makeFloatBuffer(buffer);
            this.uvBuffer = makeFloatBuffer(uv);
            this.vertexLen = buffer.length / 2;
            this.drawMode = drawMode;
            this.textureId = textureId;
        }

        public long getId() {
            return this.id;
        }

        public Body getBody() {
            return this.body;
        }

        public FloatBuffer getVertexBuffer() {
            return this.vertexBuffer;
        }

        public FloatBuffer getUvBuffer() { return this.uvBuffer;}

        public int getDrawMode() { return this.drawMode;}

        public int getVertexLen() { return this.vertexLen;}

        public int getTextureId() { return this.textureId;}
    }

    public MainRenderer(MainGlView view) {
        this.view = view;
        world = new World(0, -10);
        //this.addBox(1, 1, 0, 10, 0, BodyType.dynamicBody, 0);

    }

    private void addBodyData(Body body, float[] buffer, float[] uv, int drawMode, int textureId) {
        long id = nextBodyDataId++;
        BodyData data = new BodyData(id, body, buffer, uv, drawMode, textureId);
        this.mapBodyData.put(id, data);
    }

    private void addParticleData(ParticleSystem ps, float particleRadius, ArrayList<ArrayList<Integer>> row, int textureId) {
        long id = nextBodyDataId++;
        ParticleData data = new ParticleData(id, ps, particleRadius, row, textureId);
        this.mapParticleData.put(id, data);
    }

    public void addCircle(GL10 gl,float r, float x, float y, float angle, BodyType type, float density, int resId) {
        // Box2d用
        BodyDef bodyDef = new BodyDef();
        bodyDef.setType(type);
        bodyDef.setPosition(x, y);
        bodyDef.setAngle(angle);
        Body body = world.createBody(bodyDef);
        CircleShape shape = new CircleShape();
        shape.setRadius(r);
        body.createFixture(shape, density);
        // OpenGL用
        float vertices[] = new float[32*2];
        float uv[] = new float[32*2];
        for(int i = 0; i < 32; ++i){
            float a = ((float)Math.PI * 2.0f * i)/32;
            vertices[i*2]   = r * (float)Math.sin(a);
            vertices[i*2+1] = r * (float)Math.cos(a);

            uv[i*2]   = ((float)Math.sin(a) + 1.0f)/2f;
            uv[i*2+1] = (-1 * (float)Math.cos(a) + 1.0f)/2f;
        }
        int textureId=makeTexture(gl, resId);
        this.addBodyData(body, vertices, uv, GL10.GL_TRIANGLE_FAN, textureId);
    }

    public void addBox(GL10 gl,float hx, float hy, float x, float y, float angle, BodyType type, float density, int resId) {
        // Box2d用
        BodyDef bodyDef = new BodyDef();
        bodyDef.setType(type);
        bodyDef.setPosition(x, y);
        Body body = world.createBody(bodyDef);
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(hx, hy, 0, 0, angle);
        body.createFixture(shape, density);

        // OpenGL用
        float vertices[] = {
            - hx, + hy,
            - hx, - hy,
            + hx, + hy,
            + hx, - hy,
        };
        FloatBuffer buffer = this.makeFloatBuffer(vertices);

        float[] uv={
             0.0f,0.0f,//左上
             0.0f,1.0f,//左下
             1.0f,0.0f,//右上
             1.0f,1.0f,//右下
        };
        FloatBuffer uvBuffer = this.makeFloatBuffer(uv);
        int textureId=makeTexture(gl, resId);
        this.addBodyData(body, vertices, uv, GL10.GL_TRIANGLE_STRIP, textureId);
    }

    public void addSoftBody(GL10 gl,float hx, float hy, float cx, float cy, float particleRadius, int resId) {
        ParticleSystemDef psd = new ParticleSystemDef();
        psd.setRadius(particleRadius);
        ParticleSystem ps = world.createParticleSystem(psd);

        PolygonShape shape = new PolygonShape();
        shape.setAsBox(hx, hy, 0, 0, 0);

        ParticleGroupDef pgd = new ParticleGroupDef();
        pgd.setFlags(ParticleFlag.elasticParticle);
        pgd.setGroupFlags(ParticleGroupFlag.solidParticleGroup);
        pgd.setShape(shape);
        pgd.setPosition(cx, cy);
        ParticleGroup pg = ps.createParticleGroup(pgd);

        float py = 0;
        ArrayList<ArrayList<Integer>> row = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> line = new ArrayList<Integer>();
        for (int i = pg.getBufferIndex(); i < pg.getParticleCount() - pg.getBufferIndex(); ++i) {
            float y = ps.getParticlePositionY(i);
            if (i==0) {
                py = y;
            }

            if ((float)Math.abs(py - y) > 0.01f) {
                row.add(line);
                line = new ArrayList<Integer>();
            }
            line.add(i);
            py = y;
        }
        row.add(line);

        int textureId=makeTexture(gl, resId);
        this.addParticleData(ps, particleRadius, row, textureId);
    }

三、完整源码下载:LiquidFunTest源码: https://url83.ctfile.com/d/45573183-68059777-a5f411?p=7526 (访问密码: 7526)
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lilihewo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值