use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class LodGenerator method gatherVertexData.
private void gatherVertexData(Mesh mesh, List<Vertex> vertexLookup) {
//in case the model is currently animating with software animation
//attempting to retrieve the bind position instead of the position.
VertexBuffer position = mesh.getBuffer(VertexBuffer.Type.BindPosePosition);
if (position == null) {
position = mesh.getBuffer(VertexBuffer.Type.Position);
}
FloatBuffer pos = (FloatBuffer) position.getDataReadOnly();
pos.rewind();
while (pos.remaining() != 0) {
Vertex v = new Vertex();
v.position.setX(pos.get());
v.position.setY(pos.get());
v.position.setZ(pos.get());
v.isSeam = false;
Vertex existingV = findSimilar(v);
if (existingV != null) {
//vertex position already exists
existingV.isSeam = true;
v.isSeam = true;
} else {
vertexList.add(v);
}
vertexLookup.add(v);
}
pos.rewind();
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class TextureAtlas method applyAtlasCoords.
private static void applyAtlasCoords(List<Geometry> geometries, Mesh outMesh, TextureAtlas atlas) {
int globalVertIndex = 0;
for (Geometry geom : geometries) {
Mesh inMesh = geom.getMesh();
geom.computeWorldMatrix();
int geomVertCount = inMesh.getVertexCount();
VertexBuffer inBuf = inMesh.getBuffer(Type.TexCoord);
VertexBuffer outBuf = outMesh.getBuffer(Type.TexCoord);
if (inBuf == null || outBuf == null) {
continue;
}
atlas.applyCoords(geom, globalVertIndex, outMesh);
globalVertIndex += geomVertCount;
}
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class TextureAtlas method applyCoords.
/**
* Applies the texture coordinates to the given output mesh
* if the DiffuseMap or ColorMap of the input geometry exist in the atlas.
* @param geom The geometry to change the texture coordinate buffer on.
* @param offset Target buffer offset.
* @param outMesh The mesh to set the coords in (can be same as input).
* @return true if texture has been found and coords have been changed, false otherwise.
*/
public boolean applyCoords(Geometry geom, int offset, Mesh outMesh) {
Mesh inMesh = geom.getMesh();
geom.computeWorldMatrix();
VertexBuffer inBuf = inMesh.getBuffer(Type.TexCoord);
VertexBuffer outBuf = outMesh.getBuffer(Type.TexCoord);
if (inBuf == null || outBuf == null) {
throw new IllegalStateException("Geometry mesh has no texture coordinate buffer.");
}
Texture tex = getMaterialTexture(geom, "DiffuseMap");
if (tex == null) {
tex = getMaterialTexture(geom, "ColorMap");
}
if (tex != null) {
TextureAtlasTile tile = getAtlasTile(tex);
if (tile != null) {
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
tile.transformTextureCoords(inPos, offset, outPos);
return true;
} else {
return false;
}
} else {
throw new IllegalStateException("Geometry has no proper texture.");
}
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class PoseTrack method applyFrame.
private void applyFrame(Mesh target, int frameIndex, float weight) {
PoseFrame frame = frames[frameIndex];
VertexBuffer pb = target.getBuffer(Type.Position);
for (int i = 0; i < frame.poses.length; i++) {
Pose pose = frame.poses[i];
float poseWeight = frame.weights[i] * weight;
pose.apply(poseWeight, (FloatBuffer) pb.getData());
}
// force to re-upload data to gpu
pb.updateData(pb.getData());
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class SkeletonControl method applySkinning.
/**
* Method to apply skinning transforms to a mesh's buffers
*
* @param mesh the mesh
* @param offsetMatrices the offset matices to apply
*/
private void applySkinning(Mesh mesh, Matrix4f[] offsetMatrices) {
int maxWeightsPerVert = mesh.getMaxNumWeights();
if (maxWeightsPerVert <= 0) {
throw new IllegalStateException("Max weights per vert is incorrectly set!");
}
int fourMinusMaxWeights = 4 - maxWeightsPerVert;
// NOTE: This code assumes the vertex buffer is in bind pose
// resetToBind() has been called this frame
VertexBuffer vb = mesh.getBuffer(Type.Position);
FloatBuffer fvb = (FloatBuffer) vb.getData();
fvb.rewind();
VertexBuffer nb = mesh.getBuffer(Type.Normal);
FloatBuffer fnb = (FloatBuffer) nb.getData();
fnb.rewind();
// get boneIndexes and weights for mesh
ByteBuffer ib = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData();
FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();
ib.rewind();
wb.rewind();
float[] weights = wb.array();
byte[] indices = ib.array();
int idxWeights = 0;
TempVars vars = TempVars.get();
float[] posBuf = vars.skinPositions;
float[] normBuf = vars.skinNormals;
int iterations = (int) FastMath.ceil(fvb.limit() / ((float) posBuf.length));
int bufLength = posBuf.length;
for (int i = iterations - 1; i >= 0; i--) {
// read next set of positions and normals from native buffer
bufLength = Math.min(posBuf.length, fvb.remaining());
fvb.get(posBuf, 0, bufLength);
fnb.get(normBuf, 0, bufLength);
int verts = bufLength / 3;
int idxPositions = 0;
// iterate vertices and apply skinning transform for each effecting bone
for (int vert = verts - 1; vert >= 0; vert--) {
// Skip this vertex if the first weight is zero.
if (weights[idxWeights] == 0) {
idxPositions += 3;
idxWeights += 4;
continue;
}
float nmx = normBuf[idxPositions];
float vtx = posBuf[idxPositions++];
float nmy = normBuf[idxPositions];
float vty = posBuf[idxPositions++];
float nmz = normBuf[idxPositions];
float vtz = posBuf[idxPositions++];
float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0;
for (int w = maxWeightsPerVert - 1; w >= 0; w--) {
float weight = weights[idxWeights];
Matrix4f mat = offsetMatrices[indices[idxWeights++] & 0xff];
rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;
rnx += (nmx * mat.m00 + nmy * mat.m01 + nmz * mat.m02) * weight;
rny += (nmx * mat.m10 + nmy * mat.m11 + nmz * mat.m12) * weight;
rnz += (nmx * mat.m20 + nmy * mat.m21 + nmz * mat.m22) * weight;
}
idxWeights += fourMinusMaxWeights;
idxPositions -= 3;
normBuf[idxPositions] = rnx;
posBuf[idxPositions++] = rx;
normBuf[idxPositions] = rny;
posBuf[idxPositions++] = ry;
normBuf[idxPositions] = rnz;
posBuf[idxPositions++] = rz;
}
fvb.position(fvb.position() - bufLength);
fvb.put(posBuf, 0, bufLength);
fnb.position(fnb.position() - bufLength);
fnb.put(normBuf, 0, bufLength);
}
vars.release();
vb.updateData(fvb);
nb.updateData(fnb);
}
Aggregations