use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class SpatialTrack method setTime.
/**
*
* Modify the spatial which this track modifies.
*
* @param time
* the current time of the animation
*/
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
Spatial spatial = control.getSpatial();
Vector3f tempV = vars.vect1;
Vector3f tempS = vars.vect2;
Quaternion tempQ = vars.quat1;
Vector3f tempV2 = vars.vect3;
Vector3f tempS2 = vars.vect4;
Quaternion tempQ2 = vars.quat2;
int lastFrame = times.length - 1;
if (time < 0 || lastFrame == 0) {
if (rotations != null)
rotations.get(0, tempQ);
if (translations != null)
translations.get(0, tempV);
if (scales != null) {
scales.get(0, tempS);
}
} else if (time >= times[lastFrame]) {
if (rotations != null)
rotations.get(lastFrame, tempQ);
if (translations != null)
translations.get(lastFrame, tempV);
if (scales != null) {
scales.get(lastFrame, tempS);
}
} else {
int startFrame = 0;
int endFrame = 1;
// use lastFrame so we never overflow the array
for (int i = 0; i < lastFrame && times[i] < time; ++i) {
startFrame = i;
endFrame = i + 1;
}
float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
if (rotations != null)
rotations.get(startFrame, tempQ);
if (translations != null)
translations.get(startFrame, tempV);
if (scales != null) {
scales.get(startFrame, tempS);
}
if (rotations != null)
rotations.get(endFrame, tempQ2);
if (translations != null)
translations.get(endFrame, tempV2);
if (scales != null) {
scales.get(endFrame, tempS2);
}
tempQ.nlerp(tempQ2, blend);
tempV.interpolateLocal(tempV2, blend);
tempS.interpolateLocal(tempS2, blend);
}
if (translations != null)
spatial.setLocalTranslation(tempV);
if (rotations != null)
spatial.setLocalRotation(tempQ);
if (scales != null) {
spatial.setLocalScale(tempS);
}
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class ChaseCameraAppState method rotateCamera.
/**
* rotate the camera around the target
*/
protected void rotateCamera() {
verticalRotation = FastMath.clamp(verticalRotation, minVerticalRotation, maxVerticalRotation);
TempVars vars = TempVars.get();
Quaternion rot = vars.quat1;
Quaternion rot2 = vars.quat2;
rot.fromAngleNormalAxis(verticalRotation, leftVector);
rot2.fromAngleNormalAxis(horizontalRotation, upVector);
rot2.multLocal(rot);
target.setLocalRotation(rot2);
vars.release();
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class Skeleton method computeSkinningMatrices.
/**
* Compute the skining matrices for each bone of the skeleton that would be used to transform vertices of associated meshes
* @return
*/
public Matrix4f[] computeSkinningMatrices() {
TempVars vars = TempVars.get();
for (int i = 0; i < boneList.length; i++) {
boneList[i].getOffsetTransform(skinningMatrixes[i], vars.quat1, vars.vect1, vars.vect2, vars.tempMat3);
}
vars.release();
return skinningMatrixes;
}
use of com.jme3.util.TempVars 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);
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class SkeletonControl method applySkinningTangents.
/**
* Specific method for skinning with tangents to avoid cluttering the
* classic skinning calculation with null checks that would slow down the
* process even if tangents don't have to be computed. Also the iteration
* has additional indexes since tangent has 4 components instead of 3 for
* pos and norm
*
* @param maxWeightsPerVert maximum number of weights per vertex
* @param mesh the mesh
* @param offsetMatrices the offsetMaytrices to apply
* @param tb the tangent vertexBuffer
*/
private void applySkinningTangents(Mesh mesh, Matrix4f[] offsetMatrices, VertexBuffer tb) {
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();
FloatBuffer ftb = (FloatBuffer) tb.getData();
ftb.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;
float[] tanBuf = vars.skinTangents;
int iterations = (int) FastMath.ceil(fvb.limit() / ((float) posBuf.length));
int bufLength = 0;
int tanLength = 0;
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());
tanLength = Math.min(tanBuf.length, ftb.remaining());
fvb.get(posBuf, 0, bufLength);
fnb.get(normBuf, 0, bufLength);
ftb.get(tanBuf, 0, tanLength);
int verts = bufLength / 3;
int idxPositions = 0;
//tangents has their own index because of the 4 components
int idxTangents = 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) {
idxTangents += 4;
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 tnx = tanBuf[idxTangents++];
float tny = tanBuf[idxTangents++];
float tnz = tanBuf[idxTangents++];
// skipping the 4th component of the tangent since it doesn't have to be transformed
idxTangents++;
float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0, rtx = 0, rty = 0, rtz = 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;
rtx += (tnx * mat.m00 + tny * mat.m01 + tnz * mat.m02) * weight;
rty += (tnx * mat.m10 + tny * mat.m11 + tnz * mat.m12) * weight;
rtz += (tnx * mat.m20 + tny * mat.m21 + tnz * 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;
idxTangents -= 4;
tanBuf[idxTangents++] = rtx;
tanBuf[idxTangents++] = rty;
tanBuf[idxTangents++] = rtz;
//once again skipping the 4th component of the tangent
idxTangents++;
}
fvb.position(fvb.position() - bufLength);
fvb.put(posBuf, 0, bufLength);
fnb.position(fnb.position() - bufLength);
fnb.put(normBuf, 0, bufLength);
ftb.position(ftb.position() - tanLength);
ftb.put(tanBuf, 0, tanLength);
}
vars.release();
vb.updateData(fvb);
nb.updateData(fnb);
tb.updateData(ftb);
}
Aggregations