private CollisionShape rotate(CollisionShape shape, Quat4f rot) { if (shape instanceof BoxShape) { BoxShape box = (BoxShape) shape; javax.vecmath.Vector3f extents = box.getHalfExtentsWithMargin(new javax.vecmath.Vector3f()); com.bulletphysics.linearmath.QuaternionUtil.quatRotate(VecMath.to(rot), extents, extents); extents.absolute(); return new BoxShape(extents); } else if (shape instanceof CompoundShape) { CompoundShape compound = (CompoundShape) shape; CompoundShape newShape = new CompoundShape(); for (CompoundShapeChild child : compound.getChildList()) { CollisionShape rotatedChild = rotate(child.childShape, rot); javax.vecmath.Vector3f offset = com.bulletphysics.linearmath.QuaternionUtil.quatRotate( VecMath.to(rot), child.transform.origin, new javax.vecmath.Vector3f()); newShape.addChildShape( new Transform( new javax.vecmath.Matrix4f(VecMath.to(Rotation.none().getQuat4f()), offset, 1.0f)), rotatedChild); } return newShape; } else if (shape instanceof ConvexHullShape) { ConvexHullShape convexHull = (ConvexHullShape) shape; ObjectArrayList<javax.vecmath.Vector3f> transformedVerts = new ObjectArrayList<>(); for (javax.vecmath.Vector3f vert : convexHull.getPoints()) { transformedVerts.add( com.bulletphysics.linearmath.QuaternionUtil.quatRotate( VecMath.to(rot), vert, new javax.vecmath.Vector3f())); } return new ConvexHullShape(transformedVerts); } return shape; }
/** * Adds a new physics block to be rendered as a rigid body. Translucent blocks are ignored. * * @param position The position * @param type The block type * @param impulse An impulse * @param size The size of the block * @return The created rigid body (if any) */ public synchronized BlockRigidBody addBlock( Vector3f position, byte type, Vector3f impulse, BLOCK_SIZE size, boolean temporary) { if (temporary && _blocks.size() > MAX_TEMP_BLOCKS) return null; BoxShape shape = _blockShape; Block block = BlockManager.getInstance().getBlock(type); if (block.isTranslucent()) return null; if (size == BLOCK_SIZE.HALF_SIZE) shape = _blockShapeHalf; else if (size == BLOCK_SIZE.QUARTER_SIZE) shape = _blockShapeQuarter; Matrix3f rot = new Matrix3f(); rot.setIdentity(); DefaultMotionState blockMotionState = new DefaultMotionState(new Transform(new Matrix4f(rot, position, 1.0f))); Vector3f fallInertia = new Vector3f(); shape.calculateLocalInertia(block.getMass(), fallInertia); RigidBodyConstructionInfo blockCI = new RigidBodyConstructionInfo(block.getMass(), blockMotionState, shape, fallInertia); BlockRigidBody rigidBlock = new BlockRigidBody(blockCI, type); rigidBlock.setRestitution(0.0f); rigidBlock.setAngularFactor(0.5f); rigidBlock.setFriction(0.5f); rigidBlock._temporary = temporary; // Apply impulse rigidBlock.applyImpulse(impulse, new Vector3f(0.0f, 0.0f, 0.0f)); _insertionQueue.add(rigidBlock); return rigidBlock; }