/** Copies the specified vertices from the Mesh to the float array. The float array must be large enough to hold * destOffset+count vertices. * @param srcOffset the offset (in number of floats) of the vertices in the mesh to copy * @param count the amount of floats to copy * @param vertices the array to copy the vertices to * @param destOffset the offset (in floats) in the vertices array to start copying */ public float[] getVertices (int srcOffset, int count, float[] vertices, int destOffset) { // TODO: Perhaps this method should be vertexSize aware?? final int max = getNumVertices() * getVertexSize() / 4; if (count == -1) { count = max - srcOffset; if (count > vertices.length - destOffset) count = vertices.length - destOffset; } if (srcOffset < 0 || count <= 0 || (srcOffset + count) > max || destOffset < 0 || destOffset >= vertices.length) throw new IndexOutOfBoundsException(); if ((vertices.length - destOffset) < count) throw new IllegalArgumentException("not enough room in vertices array, has " + vertices.length + " floats, needs " + count); int pos = getVerticesBuffer().position(); getVerticesBuffer().position(srcOffset); getVerticesBuffer().get(vertices, destOffset, count); getVerticesBuffer().position(pos); return vertices; }
/** Copies the specified vertices from the Mesh to the float array. The float array must be large enough to hold * destOffset+count vertices. * @param srcOffset the offset (in number of floats) of the vertices in the mesh to copy * @param count the amount of floats to copy * @param vertices the array to copy the vertices to * @param destOffset the offset (in floats) in the vertices array to start copying */ public float[] getVertices (int srcOffset, int count, float[] vertices, int destOffset) { // TODO: Perhaps this method should be vertexSize aware?? final int max = getNumVertices() * getVertexSize() / 4; if (count == -1) { count = max - srcOffset; if (count > vertices.length - destOffset) count = vertices.length - destOffset; } if (srcOffset < 0 || count <= 0 || (srcOffset + count) > max || destOffset < 0 || destOffset >= vertices.length) throw new IndexOutOfBoundsException(); if ((vertices.length - destOffset) < count) throw new IllegalArgumentException("not enough room in vertices array, has " + vertices.length + " floats, needs " + count); int pos = getVerticesBuffer().position(); getVerticesBuffer().position(srcOffset); getVerticesBuffer().get(vertices, destOffset, count); getVerticesBuffer().position(pos); return vertices; }
/** Starts the redefinition of an existing cache, allowing the add and {@link #endCache()} methods to be called. If this is not * the last cache created, it cannot have more entries added to it than when it was first created. To do that, use * {@link #clear()} and then {@link #begin()}. */ public void beginCache (int cacheID) { if (drawing) throw new IllegalStateException("end must be called before beginCache"); if (currentCache != null) throw new IllegalStateException("endCache must be called before begin."); if (cacheID == caches.size - 1) { Cache oldCache = caches.removeIndex(cacheID); mesh.getVerticesBuffer().limit(oldCache.offset); beginCache(); return; } currentCache = caches.get(cacheID); mesh.getVerticesBuffer().position(currentCache.offset); }
/** Starts the redefinition of an existing cache, allowing the add and {@link #endCache()} methods to be called. If this is not * the last cache created, it cannot have more entries added to it than when it was first created. To do that, use * {@link #clear()} and then {@link #begin()}. */ public void beginCache (int cacheID) { if (drawing) throw new IllegalStateException("end must be called before beginCache"); if (currentCache != null) throw new IllegalStateException("endCache must be called before begin."); if (cacheID == caches.size - 1) { Cache oldCache = caches.removeIndex(cacheID); mesh.getVerticesBuffer().limit(oldCache.offset); beginCache(); return; } currentCache = caches.get(cacheID); mesh.getVerticesBuffer().position(currentCache.offset); }
/** Starts the definition of a new cache, allowing the add and {@link #endCache()} methods to be called. */ public void beginCache () { if (drawing) throw new IllegalStateException("end must be called before beginCache"); if (currentCache != null) throw new IllegalStateException("endCache must be called before begin."); int verticesPerImage = mesh.getNumIndices() > 0 ? 4 : 6; currentCache = new Cache(caches.size, mesh.getVerticesBuffer().limit()); caches.add(currentCache); mesh.getVerticesBuffer().compact(); }
/** Starts the definition of a new cache, allowing the add and {@link #endCache()} methods to be called. */ public void beginCache () { if (drawing) throw new IllegalStateException("end must be called before beginCache"); if (currentCache != null) throw new IllegalStateException("endCache must be called before begin."); int verticesPerImage = mesh.getNumIndices() > 0 ? 4 : 6; currentCache = new Cache(caches.size, mesh.getVerticesBuffer().limit()); caches.add(currentCache); mesh.getVerticesBuffer().compact(); }
/** Invalidates all cache IDs and resets the SpriteCache so new caches can be added. */ public void clear () { caches.clear(); mesh.getVerticesBuffer().clear().flip(); }
/** Invalidates all cache IDs and resets the SpriteCache so new caches can be added. */ public void clear () { caches.clear(); mesh.getVerticesBuffer().clear().flip(); }
/** Adds the specified vertices to the cache. Each vertex should have 5 elements, one for each of the attributes: x, y, color, * u, and v. If indexed geometry is used, each image should be specified as 4 vertices, otherwise each image should be * specified as 6 vertices. */ public void add (Texture texture, float[] vertices, int offset, int length) { if (currentCache == null) throw new IllegalStateException("beginCache must be called before add."); int verticesPerImage = mesh.getNumIndices() > 0 ? 4 : 6; int count = length / (verticesPerImage * VERTEX_SIZE) * 6; int lastIndex = textures.size - 1; if (lastIndex < 0 || textures.get(lastIndex) != texture) { textures.add(texture); counts.add(count); } else counts.incr(lastIndex, count); mesh.getVerticesBuffer().put(vertices, offset, length); }
/** Adds the specified vertices to the cache. Each vertex should have 5 elements, one for each of the attributes: x, y, color, * u, and v. If indexed geometry is used, each image should be specified as 4 vertices, otherwise each image should be * specified as 6 vertices. */ public void add (Texture texture, float[] vertices, int offset, int length) { if (currentCache == null) throw new IllegalStateException("beginCache must be called before add."); int verticesPerImage = mesh.getNumIndices() > 0 ? 4 : 6; int count = length / (verticesPerImage * VERTEX_SIZE) * 6; int lastIndex = textures.size - 1; if (lastIndex < 0 || textures.get(lastIndex) != texture) { textures.add(texture); counts.add(count); } else counts.incr(lastIndex, count); mesh.getVerticesBuffer().put(vertices, offset, length); }
@Override protected void renderWorld () { softBody.getVertices(mesh.getVerticesBuffer(), softBody.getNodeCount(), mesh.getVertexSize(), 0); softBody.getWorldTransform(instance.transform); super.renderWorld(); // modelBatch.begin(camera); // world.render(modelBatch, lights); // modelBatch.render(instance, lights); // modelBatch.end(); }
/** Convenience method to set this btIndexedMesh to the specified {@link Mesh} * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. * The buffers for the vertices and indices are shared amonst both. */ public void set(final Object tag, final Mesh mesh, int offset, int count) { if ((count <= 0) || ((count % 3) != 0)) throw new com.badlogic.gdx.utils.GdxRuntimeException("Mesh must be indexed and triangulated"); VertexAttribute posAttr = mesh.getVertexAttribute(Usage.Position); if (posAttr == null) throw new com.badlogic.gdx.utils.GdxRuntimeException("Mesh doesn't have a position attribute"); set(tag, mesh.getVerticesBuffer(), mesh.getVertexSize(), mesh.getNumVertices(), posAttr.offset, mesh.getIndicesBuffer(), offset, count); }
@Override public void render () { if (world.renderMeshes) { MeshPart meshPart = model.nodes.get(0).parts.get(0).meshPart; softBody.getVertices(meshPart.mesh.getVerticesBuffer(), meshPart.mesh.getVertexSize(), positionOffset, normalOffset, meshPart.mesh.getIndicesBuffer(), meshPart.offset, meshPart.size, indexMap, 0); softBody.getWorldTransform(entity.transform); } super.render(); }
/** Convenience method to set this btIndexedMesh to the specified {@link Mesh} * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. * The buffers for the vertices and indices are shared amonst both. */ public void set(final Object tag, final Mesh mesh, int offset, int count) { if ((count <= 0) || ((count % 3) != 0)) throw new com.badlogic.gdx.utils.GdxRuntimeException("Mesh must be indexed and triangulated"); VertexAttribute posAttr = mesh.getVertexAttribute(Usage.Position); if (posAttr == null) throw new com.badlogic.gdx.utils.GdxRuntimeException("Mesh doesn't have a position attribute"); set(tag, mesh.getVerticesBuffer(), mesh.getVertexSize(), mesh.getNumVertices(), posAttr.offset, mesh.getIndicesBuffer(), offset, count); }
FloatBuffer verticesBuffer = mesh.getVerticesBuffer(); ShortBuffer indicesBuffer = mesh.getIndicesBuffer();
public static btConvexHullShape createConvexHullShape (final Model model, boolean optimize) { final Mesh mesh = model.meshes.get(0); final btConvexHullShape shape = new btConvexHullShape(mesh.getVerticesBuffer(), mesh.getNumVertices(), mesh.getVertexSize()); if (!optimize) return shape; // now optimize the shape final btShapeHull hull = new btShapeHull(shape); hull.buildHull(shape.getMargin()); final btConvexHullShape result = new btConvexHullShape(hull); // delete the temporary shape shape.dispose(); hull.dispose(); return result; }
public static btConvexHullShape createConvexHullShape (final Model model, boolean optimize) { final Mesh mesh = model.meshes.get(0); final btConvexHullShape shape = new btConvexHullShape(mesh.getVerticesBuffer(), mesh.getNumVertices(), mesh.getVertexSize()); if (!optimize) return shape; // now optimize the shape final btShapeHull hull = new btShapeHull(shape); hull.buildHull(shape.getMargin()); final btConvexHullShape result = new btConvexHullShape(hull); // delete the temporary shape shape.dispose(); hull.dispose(); return result; } }
protected void convertMesh (ModelMesh modelMesh) { int numIndices = 0; for (ModelMeshPart part : modelMesh.parts) { numIndices += part.indices.length; } VertexAttributes attributes = new VertexAttributes(modelMesh.attributes); int numVertices = modelMesh.vertices.length / (attributes.vertexSize / 4); Mesh mesh = new Mesh(true, numVertices, numIndices, attributes); meshes.add(mesh); disposables.add(mesh); BufferUtils.copy(modelMesh.vertices, mesh.getVerticesBuffer(), modelMesh.vertices.length, 0); int offset = 0; mesh.getIndicesBuffer().clear(); for (ModelMeshPart part : modelMesh.parts) { MeshPart meshPart = new MeshPart(); meshPart.id = part.id; meshPart.primitiveType = part.primitiveType; meshPart.offset = offset; meshPart.size = part.indices.length; meshPart.mesh = mesh; mesh.getIndicesBuffer().put(part.indices); offset += meshPart.size; meshParts.add(meshPart); } mesh.getIndicesBuffer().position(0); for (MeshPart part : meshParts) part.update(); }
protected void convertMesh (ModelMesh modelMesh) { int numIndices = 0; for (ModelMeshPart part : modelMesh.parts) { numIndices += part.indices.length; } VertexAttributes attributes = new VertexAttributes(modelMesh.attributes); int numVertices = modelMesh.vertices.length / (attributes.vertexSize / 4); Mesh mesh = new Mesh(true, numVertices, numIndices, attributes); meshes.add(mesh); disposables.add(mesh); BufferUtils.copy(modelMesh.vertices, mesh.getVerticesBuffer(), modelMesh.vertices.length, 0); int offset = 0; mesh.getIndicesBuffer().clear(); for (ModelMeshPart part : modelMesh.parts) { MeshPart meshPart = new MeshPart(); meshPart.id = part.id; meshPart.primitiveType = part.primitiveType; meshPart.offset = offset; meshPart.size = part.indices.length; meshPart.mesh = mesh; mesh.getIndicesBuffer().put(part.indices); offset += meshPart.size; meshParts.add(meshPart); } mesh.getIndicesBuffer().position(0); for (MeshPart part : meshParts) part.update(); }
@Override public void create () { super.create(); world.maxSubSteps = 20; world.add("ground", 0f, 0f, 0f).setColor(0.25f + 0.5f * (float)Math.random(), 0.25f + 0.5f * (float)Math.random(), 0.25f + 0.5f * (float)Math.random(), 1f); // Note: not every model is suitable for a one on one translation with a soft body, a better model might be added later. model = objLoader.loadModel(Gdx.files.internal("data/wheel.obj")); MeshPart meshPart = model.nodes.get(0).parts.get(0).meshPart; meshPart.mesh.scale(6, 6, 6); indexMap = BufferUtils.newShortBuffer(meshPart.size); positionOffset = meshPart.mesh.getVertexAttribute(Usage.Position).offset; normalOffset = meshPart.mesh.getVertexAttribute(Usage.Normal).offset; softBody = new btSoftBody(worldInfo, meshPart.mesh.getVerticesBuffer(), meshPart.mesh.getVertexSize(), positionOffset, normalOffset, meshPart.mesh.getIndicesBuffer(), meshPart.offset, meshPart.size, indexMap, 0); // Set mass of the first vertex to zero so its unmovable, comment out this line to make it a fully dynamic body. softBody.setMass(0, 0); com.badlogic.gdx.physics.bullet.softbody.btSoftBody.Material pm = softBody.appendMaterial(); pm.setKLST(0.2f); pm.setFlags(0); softBody.generateBendingConstraints(2, pm); // Be careful increasing iterations, it decreases performance (but increases accuracy). softBody.setConfig_piterations(7); softBody.setConfig_kDF(0.2f); softBody.randomizeConstraints(); softBody.setTotalMass(1); softBody.translate(tmpV.set(1, 5, 1)); ((btSoftRigidDynamicsWorld)(world.collisionWorld)).addSoftBody(softBody); world.add(entity = new BulletEntity(model, (btCollisionObject)null, 1, 5, 1)); }