Search in sources :

Example 6 with ManifoldPoint

use of com.bulletphysics.collision.narrowphase.ManifoldPoint in project Terasology by MovingBlocks.

the class BulletPhysics method getNewCollisionPairs.

private Collection<? extends PhysicsSystem.CollisionPair> getNewCollisionPairs() {
    List<PhysicsSystem.CollisionPair> collisionPairs = Lists.newArrayList();
    DynamicsWorld world = discreteDynamicsWorld;
    ObjectArrayList<PersistentManifold> manifolds = new ObjectArrayList<>();
    for (PairCachingGhostObject trigger : entityTriggers.values()) {
        EntityRef entity = (EntityRef) trigger.getUserPointer();
        for (BroadphasePair initialPair : trigger.getOverlappingPairCache().getOverlappingPairArray()) {
            EntityRef otherEntity = null;
            if (initialPair.pProxy0.clientObject == trigger) {
                if (((CollisionObject) initialPair.pProxy1.clientObject).getUserPointer() instanceof EntityRef) {
                    otherEntity = (EntityRef) ((CollisionObject) initialPair.pProxy1.clientObject).getUserPointer();
                }
            } else {
                if (((CollisionObject) initialPair.pProxy0.clientObject).getUserPointer() instanceof EntityRef) {
                    otherEntity = (EntityRef) ((CollisionObject) initialPair.pProxy0.clientObject).getUserPointer();
                }
            }
            if (otherEntity == null || otherEntity == EntityRef.NULL) {
                continue;
            }
            BroadphasePair pair = world.getPairCache().findPair(initialPair.pProxy0, initialPair.pProxy1);
            if (pair == null) {
                continue;
            }
            manifolds.clear();
            if (pair.algorithm != null) {
                pair.algorithm.getAllContactManifolds(manifolds);
            }
            for (PersistentManifold manifold : manifolds) {
                for (int point = 0; point < manifold.getNumContacts(); ++point) {
                    ManifoldPoint manifoldPoint = manifold.getContactPoint(point);
                    if (manifoldPoint.getDistance() < 0) {
                        collisionPairs.add(new PhysicsSystem.CollisionPair(entity, otherEntity, VecMath.from(manifoldPoint.positionWorldOnA), VecMath.from(manifoldPoint.positionWorldOnB), manifoldPoint.getDistance(), VecMath.from(manifoldPoint.normalWorldOnB)));
                        break;
                    }
                }
            }
        }
    }
    return collisionPairs;
}
Also used : ManifoldPoint(com.bulletphysics.collision.narrowphase.ManifoldPoint) PersistentManifold(com.bulletphysics.collision.narrowphase.PersistentManifold) BroadphasePair(com.bulletphysics.collision.broadphase.BroadphasePair) PairCachingGhostObject(com.bulletphysics.collision.dispatch.PairCachingGhostObject) ManifoldPoint(com.bulletphysics.collision.narrowphase.ManifoldPoint) CollisionObject(com.bulletphysics.collision.dispatch.CollisionObject) PhysicsSystem(org.terasology.physics.engine.PhysicsSystem) ObjectArrayList(com.bulletphysics.util.ObjectArrayList) EntityRef(org.terasology.entitySystem.entity.EntityRef) DiscreteDynamicsWorld(com.bulletphysics.dynamics.DiscreteDynamicsWorld) DynamicsWorld(com.bulletphysics.dynamics.DynamicsWorld)

Example 7 with ManifoldPoint

use of com.bulletphysics.collision.narrowphase.ManifoldPoint in project bdx by GoranM.

the class DiscreteDynamicsWorld method debugDrawWorld.

@Override
public void debugDrawWorld() {
    Stack stack = Stack.enter();
    if (getDebugDrawer() != null && (getDebugDrawer().getDebugMode() & DebugDrawModes.DRAW_CONTACT_POINTS) != 0) {
        int numManifolds = getDispatcher().getNumManifolds();
        Vector3f color = stack.allocVector3f();
        color.set(0f, 0f, 0f);
        for (int i = 0; i < numManifolds; i++) {
            PersistentManifold contactManifold = getDispatcher().getManifoldByIndexInternal(i);
            //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
            //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
            int numContacts = contactManifold.getNumContacts();
            for (int j = 0; j < numContacts; j++) {
                ManifoldPoint cp = contactManifold.getContactPoint(j);
                getDebugDrawer().drawContactPoint(cp.positionWorldOnB, cp.normalWorldOnB, cp.getDistance(), cp.getLifeTime(), color);
            }
        }
    }
    if (getDebugDrawer() != null && (getDebugDrawer().getDebugMode() & (DebugDrawModes.DRAW_WIREFRAME | DebugDrawModes.DRAW_AABB)) != 0) {
        int i;
        Transform tmpTrans = stack.allocTransform();
        Vector3f minAabb = stack.allocVector3f();
        Vector3f maxAabb = stack.allocVector3f();
        Vector3f colorvec = stack.allocVector3f();
        // todo: iterate over awake simulation islands!
        for (i = 0; i < collisionObjects.size(); i++) {
            CollisionObject colObj = collisionObjects.getQuick(i);
            if (getDebugDrawer() != null && (getDebugDrawer().getDebugMode() & DebugDrawModes.DRAW_WIREFRAME) != 0) {
                Vector3f color = stack.allocVector3f();
                color.set(255f, 255f, 255f);
                switch(colObj.getActivationState()) {
                    case CollisionObject.ACTIVE_TAG:
                        color.set(255f, 255f, 255f);
                        break;
                    case CollisionObject.ISLAND_SLEEPING:
                        color.set(0f, 255f, 0f);
                        break;
                    case CollisionObject.WANTS_DEACTIVATION:
                        color.set(0f, 255f, 255f);
                        break;
                    case CollisionObject.DISABLE_DEACTIVATION:
                        color.set(255f, 0f, 0f);
                        break;
                    case CollisionObject.DISABLE_SIMULATION:
                        color.set(255f, 255f, 0f);
                        break;
                    default:
                        {
                            color.set(255f, 0f, 0f);
                        }
                }
                debugDrawObject(colObj.getWorldTransform(tmpTrans), colObj.getCollisionShape(), color);
            }
            if (debugDrawer != null && (debugDrawer.getDebugMode() & DebugDrawModes.DRAW_AABB) != 0) {
                colorvec.set(1f, 0f, 0f);
                colObj.getCollisionShape().getAabb(colObj.getWorldTransform(tmpTrans), minAabb, maxAabb);
                debugDrawer.drawAabb(minAabb, maxAabb, colorvec);
            }
        }
        Vector3f wheelColor = stack.allocVector3f();
        Vector3f wheelPosWS = stack.allocVector3f();
        Vector3f axle = stack.allocVector3f();
        Vector3f tmp = stack.allocVector3f();
        for (i = 0; i < vehicles.size(); i++) {
            for (int v = 0; v < vehicles.getQuick(i).getNumWheels(); v++) {
                wheelColor.set(0, 255, 255);
                if (vehicles.getQuick(i).getWheelInfo(v).raycastInfo.isInContact) {
                    wheelColor.set(0, 0, 255);
                } else {
                    wheelColor.set(255, 0, 255);
                }
                wheelPosWS.set(vehicles.getQuick(i).getWheelInfo(v).worldTransform.origin);
                axle.set(vehicles.getQuick(i).getWheelInfo(v).worldTransform.basis.getElement(0, vehicles.getQuick(i).getRightAxis()), vehicles.getQuick(i).getWheelInfo(v).worldTransform.basis.getElement(1, vehicles.getQuick(i).getRightAxis()), vehicles.getQuick(i).getWheelInfo(v).worldTransform.basis.getElement(2, vehicles.getQuick(i).getRightAxis()));
                //m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS
                //debug wheels (cylinders)
                tmp.add(wheelPosWS, axle);
                debugDrawer.drawLine(wheelPosWS, tmp, wheelColor);
                debugDrawer.drawLine(wheelPosWS, vehicles.getQuick(i).getWheelInfo(v).raycastInfo.contactPointWS, wheelColor);
            }
        }
        if (getDebugDrawer() != null && getDebugDrawer().getDebugMode() != 0) {
            for (i = 0; i < actions.size(); i++) {
                actions.getQuick(i).debugDraw(debugDrawer);
            }
        }
    }
    stack.leave();
}
Also used : CollisionObject(com.bulletphysics.collision.dispatch.CollisionObject) ManifoldPoint(com.bulletphysics.collision.narrowphase.ManifoldPoint) PersistentManifold(com.bulletphysics.collision.narrowphase.PersistentManifold) Vector3f(javax.vecmath.Vector3f) Transform(com.bulletphysics.linearmath.Transform) TypedConstraint(com.bulletphysics.dynamics.constraintsolver.TypedConstraint) ManifoldPoint(com.bulletphysics.collision.narrowphase.ManifoldPoint) Stack(com.bulletphysics.util.Stack)

Example 8 with ManifoldPoint

use of com.bulletphysics.collision.narrowphase.ManifoldPoint in project bdx by GoranM.

the class KinematicCharacterController method recoverFromPenetration.

protected boolean recoverFromPenetration(CollisionWorld collisionWorld) {
    boolean penetration = false;
    Stack stack = Stack.enter();
    collisionWorld.getDispatcher().dispatchAllCollisionPairs(ghostObject.getOverlappingPairCache(), collisionWorld.getDispatchInfo(), collisionWorld.getDispatcher());
    currentPosition.set(ghostObject.getWorldTransform(stack.allocTransform()).origin);
    float maxPen = 0.0f;
    for (int i = 0; i < ghostObject.getOverlappingPairCache().getNumOverlappingPairs(); i++) {
        manifoldArray.clear();
        BroadphasePair collisionPair = ghostObject.getOverlappingPairCache().getOverlappingPairArray().getQuick(i);
        if (collisionPair.algorithm != null) {
            collisionPair.algorithm.getAllContactManifolds(manifoldArray);
        }
        for (int j = 0; j < manifoldArray.size(); j++) {
            PersistentManifold manifold = manifoldArray.getQuick(j);
            float directionSign = manifold.getBody0() == ghostObject ? -1.0f : 1.0f;
            for (int p = 0; p < manifold.getNumContacts(); p++) {
                ManifoldPoint pt = manifold.getContactPoint(p);
                float dist = pt.getDistance();
                if (dist < 0.0f) {
                    if (dist < maxPen) {
                        maxPen = dist;
                        //??
                        touchingNormal.set(pt.normalWorldOnB);
                        touchingNormal.scale(directionSign);
                    }
                    currentPosition.scaleAdd(directionSign * dist * 0.2f, pt.normalWorldOnB, currentPosition);
                    penetration = true;
                } else {
                //printf("touching %f\n", dist);
                }
            }
        //manifold->clearManifold();
        }
    }
    Transform newTrans = ghostObject.getWorldTransform(stack.allocTransform());
    newTrans.origin.set(currentPosition);
    ghostObject.setWorldTransform(newTrans);
    //printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
    //System.out.println("recoverFromPenetration "+penetration+" "+touchingNormal);
    stack.leave();
    return penetration;
}
Also used : ManifoldPoint(com.bulletphysics.collision.narrowphase.ManifoldPoint) PersistentManifold(com.bulletphysics.collision.narrowphase.PersistentManifold) BroadphasePair(com.bulletphysics.collision.broadphase.BroadphasePair) Transform(com.bulletphysics.linearmath.Transform) ManifoldPoint(com.bulletphysics.collision.narrowphase.ManifoldPoint) Stack(com.bulletphysics.util.Stack)

Example 9 with ManifoldPoint

use of com.bulletphysics.collision.narrowphase.ManifoldPoint in project bdx by GoranM.

the class SequentialImpulseConstraintSolver method prepareConstraints.

protected void prepareConstraints(PersistentManifold manifoldPtr, ContactSolverInfo info, IDebugDraw debugDrawer) {
    Stack stack = Stack.enter();
    RigidBody body0 = (RigidBody) manifoldPtr.getBody0();
    RigidBody body1 = (RigidBody) manifoldPtr.getBody1();
    // only necessary to refresh the manifold once (first iteration). The integration is done outside the loop
    {
        //#ifdef FORCE_REFESH_CONTACT_MANIFOLDS
        //manifoldPtr->refreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform());
        //#endif //FORCE_REFESH_CONTACT_MANIFOLDS		
        int numpoints = manifoldPtr.getNumContacts();
        BulletStats.gTotalContactPoints += numpoints;
        Vector3f tmpVec = stack.allocVector3f();
        Matrix3f tmpMat3 = stack.allocMatrix3f();
        Vector3f pos1 = stack.allocVector3f();
        Vector3f pos2 = stack.allocVector3f();
        Vector3f rel_pos1 = stack.allocVector3f();
        Vector3f rel_pos2 = stack.allocVector3f();
        Vector3f vel1 = stack.allocVector3f();
        Vector3f vel2 = stack.allocVector3f();
        Vector3f vel = stack.allocVector3f();
        Vector3f totalImpulse = stack.allocVector3f();
        Vector3f torqueAxis0 = stack.allocVector3f();
        Vector3f torqueAxis1 = stack.allocVector3f();
        Vector3f ftorqueAxis0 = stack.allocVector3f();
        Vector3f ftorqueAxis1 = stack.allocVector3f();
        for (int i = 0; i < numpoints; i++) {
            ManifoldPoint cp = manifoldPtr.getContactPoint(i);
            if (cp.getDistance() <= 0f) {
                cp.getPositionWorldOnA(pos1);
                cp.getPositionWorldOnB(pos2);
                rel_pos1.sub(pos1, body0.getCenterOfMassPosition(tmpVec));
                rel_pos2.sub(pos2, body1.getCenterOfMassPosition(tmpVec));
                // this jacobian entry is re-used for all iterations
                Matrix3f mat1 = body0.getCenterOfMassTransform(stack.allocTransform()).basis;
                mat1.transpose();
                Matrix3f mat2 = body1.getCenterOfMassTransform(stack.allocTransform()).basis;
                mat2.transpose();
                JacobianEntry jac = jacobiansPool.get();
                jac.init(mat1, mat2, rel_pos1, rel_pos2, cp.normalWorldOnB, body0.getInvInertiaDiagLocal(stack.allocVector3f()), body0.getInvMass(), body1.getInvInertiaDiagLocal(stack.allocVector3f()), body1.getInvMass());
                float jacDiagAB = jac.getDiagonal();
                jacobiansPool.release(jac);
                ConstraintPersistentData cpd = (ConstraintPersistentData) cp.userPersistentData;
                if (cpd != null) {
                    // might be invalid
                    cpd.persistentLifeTime++;
                    if (cpd.persistentLifeTime != cp.getLifeTime()) {
                        //printf("Invalid: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime());
                        //new (cpd) btConstraintPersistentData;
                        cpd.reset();
                        cpd.persistentLifeTime = cp.getLifeTime();
                    } else {
                    //printf("Persistent: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime());
                    }
                } else {
                    // todo: should this be in a pool?
                    //void* mem = btAlignedAlloc(sizeof(btConstraintPersistentData),16);
                    //cpd = new (mem)btConstraintPersistentData;
                    cpd = new ConstraintPersistentData();
                    //assert(cpd != null);
                    totalCpd++;
                    //printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd);
                    cp.userPersistentData = cpd;
                    cpd.persistentLifeTime = cp.getLifeTime();
                //printf("CREATED: %x . cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd,cpd->m_persistentLifeTime,cp.getLifeTime());
                }
                assert (cpd != null);
                cpd.jacDiagABInv = 1f / jacDiagAB;
                // Dependent on Rigidbody A and B types, fetch the contact/friction response func
                // perhaps do a similar thing for friction/restutution combiner funcs...
                cpd.frictionSolverFunc = frictionDispatch[body0.frictionSolverType][body1.frictionSolverType];
                cpd.contactSolverFunc = contactDispatch[body0.contactSolverType][body1.contactSolverType];
                body0.getVelocityInLocalPoint(rel_pos1, vel1);
                body1.getVelocityInLocalPoint(rel_pos2, vel2);
                vel.sub(vel1, vel2);
                float rel_vel;
                rel_vel = cp.normalWorldOnB.dot(vel);
                float combinedRestitution = cp.combinedRestitution;
                ///btScalar(info.m_numIterations);
                cpd.penetration = cp.getDistance();
                cpd.friction = cp.combinedFriction;
                cpd.restitution = restitutionCurve(rel_vel, combinedRestitution);
                if (cpd.restitution <= 0f) {
                    cpd.restitution = 0f;
                }
                // restitution and penetration work in same direction so
                // rel_vel 
                float penVel = -cpd.penetration / info.timeStep;
                if (cpd.restitution > penVel) {
                    cpd.penetration = 0f;
                }
                float relaxation = info.damping;
                if ((info.solverMode & SolverMode.SOLVER_USE_WARMSTARTING) != 0) {
                    cpd.appliedImpulse *= relaxation;
                } else {
                    cpd.appliedImpulse = 0f;
                }
                // for friction
                cpd.prevAppliedImpulse = cpd.appliedImpulse;
                // re-calculate friction direction every frame, todo: check if this is really needed
                TransformUtil.planeSpace1(cp.normalWorldOnB, cpd.frictionWorldTangential0, cpd.frictionWorldTangential1);
                //#define NO_FRICTION_WARMSTART 1
                //#ifdef NO_FRICTION_WARMSTART
                cpd.accumulatedTangentImpulse0 = 0f;
                cpd.accumulatedTangentImpulse1 = 0f;
                //#endif //NO_FRICTION_WARMSTART
                float denom0 = body0.computeImpulseDenominator(pos1, cpd.frictionWorldTangential0);
                float denom1 = body1.computeImpulseDenominator(pos2, cpd.frictionWorldTangential0);
                float denom = relaxation / (denom0 + denom1);
                cpd.jacDiagABInvTangent0 = denom;
                denom0 = body0.computeImpulseDenominator(pos1, cpd.frictionWorldTangential1);
                denom1 = body1.computeImpulseDenominator(pos2, cpd.frictionWorldTangential1);
                denom = relaxation / (denom0 + denom1);
                cpd.jacDiagABInvTangent1 = denom;
                //btVector3 totalImpulse = 
                //	//#ifndef NO_FRICTION_WARMSTART
                //	//cpd->m_frictionWorldTangential0*cpd->m_accumulatedTangentImpulse0+
                //	//cpd->m_frictionWorldTangential1*cpd->m_accumulatedTangentImpulse1+
                //	//#endif //NO_FRICTION_WARMSTART
                //	cp.normalWorldOnB*cpd.appliedImpulse;
                totalImpulse.scale(cpd.appliedImpulse, cp.normalWorldOnB);
                ///
                {
                    torqueAxis0.cross(rel_pos1, cp.normalWorldOnB);
                    cpd.angularComponentA.set(torqueAxis0);
                    body0.getInvInertiaTensorWorld(tmpMat3).transform(cpd.angularComponentA);
                    torqueAxis1.cross(rel_pos2, cp.normalWorldOnB);
                    cpd.angularComponentB.set(torqueAxis1);
                    body1.getInvInertiaTensorWorld(tmpMat3).transform(cpd.angularComponentB);
                }
                {
                    ftorqueAxis0.cross(rel_pos1, cpd.frictionWorldTangential0);
                    cpd.frictionAngularComponent0A.set(ftorqueAxis0);
                    body0.getInvInertiaTensorWorld(tmpMat3).transform(cpd.frictionAngularComponent0A);
                }
                {
                    ftorqueAxis1.cross(rel_pos1, cpd.frictionWorldTangential1);
                    cpd.frictionAngularComponent1A.set(ftorqueAxis1);
                    body0.getInvInertiaTensorWorld(tmpMat3).transform(cpd.frictionAngularComponent1A);
                }
                {
                    ftorqueAxis0.cross(rel_pos2, cpd.frictionWorldTangential0);
                    cpd.frictionAngularComponent0B.set(ftorqueAxis0);
                    body1.getInvInertiaTensorWorld(tmpMat3).transform(cpd.frictionAngularComponent0B);
                }
                {
                    ftorqueAxis1.cross(rel_pos2, cpd.frictionWorldTangential1);
                    cpd.frictionAngularComponent1B.set(ftorqueAxis1);
                    body1.getInvInertiaTensorWorld(tmpMat3).transform(cpd.frictionAngularComponent1B);
                }
                ///
                // apply previous frames impulse on both bodies
                body0.applyImpulse(totalImpulse, rel_pos1);
                tmpVec.negate(totalImpulse);
                body1.applyImpulse(tmpVec, rel_pos2);
            }
        }
    }
    stack.leave();
}
Also used : ManifoldPoint(com.bulletphysics.collision.narrowphase.ManifoldPoint) Matrix3f(javax.vecmath.Matrix3f) Vector3f(javax.vecmath.Vector3f) RigidBody(com.bulletphysics.dynamics.RigidBody) Stack(com.bulletphysics.util.Stack)

Aggregations

ManifoldPoint (com.bulletphysics.collision.narrowphase.ManifoldPoint)9 PersistentManifold (com.bulletphysics.collision.narrowphase.PersistentManifold)5 Stack (com.bulletphysics.util.Stack)5 CollisionObject (com.bulletphysics.collision.dispatch.CollisionObject)4 Vector3f (javax.vecmath.Vector3f)4 Transform (com.bulletphysics.linearmath.Transform)3 BroadphasePair (com.bulletphysics.collision.broadphase.BroadphasePair)2 PairCachingGhostObject (com.bulletphysics.collision.dispatch.PairCachingGhostObject)2 RigidBody (com.bulletphysics.dynamics.RigidBody)2 TypedConstraint (com.bulletphysics.dynamics.constraintsolver.TypedConstraint)2 Matrix3f (javax.vecmath.Matrix3f)2 ContactAddedCallback (com.bulletphysics.ContactAddedCallback)1 ContactDestroyedCallback (com.bulletphysics.ContactDestroyedCallback)1 ContactProcessedCallback (com.bulletphysics.ContactProcessedCallback)1 DiscreteDynamicsWorld (com.bulletphysics.dynamics.DiscreteDynamicsWorld)1 DynamicsWorld (com.bulletphysics.dynamics.DynamicsWorld)1 ObjectArrayList (com.bulletphysics.util.ObjectArrayList)1 PhysicsCollisionObject (com.jme3.bullet.collision.PhysicsCollisionObject)1 PhysicsJoint (com.jme3.bullet.joints.PhysicsJoint)1 PhysicsGhostObject (com.jme3.bullet.objects.PhysicsGhostObject)1