* Animated models won't be updated unless they are in the camera frustum ... Hopefully this won't break anything
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7290 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
1ace200526
commit
bfe772dd71
@ -36,10 +36,17 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
|
|||||||
* The skelrton of the model
|
* The skelrton of the model
|
||||||
*/
|
*/
|
||||||
private Skeleton skeleton;
|
private Skeleton skeleton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of targets which this controller effects.
|
* List of targets which this controller effects.
|
||||||
*/
|
*/
|
||||||
Mesh[] targets;
|
private Mesh[] targets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to track when a mesh was updated. Meshes are only updated
|
||||||
|
* if they are visible in at least one camera.
|
||||||
|
*/
|
||||||
|
private boolean wasMeshUpdated = false;
|
||||||
|
|
||||||
public SkeletonControl() {
|
public SkeletonControl() {
|
||||||
}
|
}
|
||||||
@ -50,21 +57,43 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void controlUpdate(float tpf) {
|
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||||
resetToBind(); // reset morph meshes to bind pose
|
if (!wasMeshUpdated){
|
||||||
|
resetToBind(); // reset morph meshes to bind pose
|
||||||
|
|
||||||
Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices();
|
Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices();
|
||||||
|
|
||||||
// if hardware skinning is supported, the matrices and weight buffer
|
// if hardware skinning is supported, the matrices and weight buffer
|
||||||
// will be sent by the SkinningShaderLogic object assigned to the shader
|
// will be sent by the SkinningShaderLogic object assigned to the shader
|
||||||
for (int i = 0; i < targets.length; i++) {
|
for (int i = 0; i < targets.length; i++) {
|
||||||
// only update targets with bone-vertex assignments
|
// only update targets with bone-vertex assignments
|
||||||
if (targets[i].getBuffer(Type.BoneIndex) != null) {
|
if (targets[i].getBuffer(Type.BoneIndex) != null) {
|
||||||
softwareSkinUpdate(targets[i], offsetMatrices);
|
softwareSkinUpdate(targets[i], offsetMatrices);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wasMeshUpdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
wasMeshUpdated = false;
|
||||||
|
|
||||||
|
// resetToBind(); // reset morph meshes to bind pose
|
||||||
|
//
|
||||||
|
// Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices();
|
||||||
|
//
|
||||||
|
// // if hardware skinning is supported, the matrices and weight buffer
|
||||||
|
// // will be sent by the SkinningShaderLogic object assigned to the shader
|
||||||
|
// for (int i = 0; i < targets.length; i++) {
|
||||||
|
// // only update targets with bone-vertex assignments
|
||||||
|
// if (targets[i].getBuffer(Type.BoneIndex) != null) {
|
||||||
|
// softwareSkinUpdate(targets[i], offsetMatrices);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
void resetToBind() {
|
void resetToBind() {
|
||||||
for (int i = 0; i < targets.length; i++) {
|
for (int i = 0; i < targets.length; i++) {
|
||||||
Mesh mesh = targets[i];
|
Mesh mesh = targets[i];
|
||||||
@ -92,6 +121,70 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Control cloneForSpatial(Spatial spatial) {
|
||||||
|
Node clonedNode = (Node) spatial;
|
||||||
|
AnimControl ctrl = spatial.getControl(AnimControl.class);
|
||||||
|
SkeletonControl clone = new SkeletonControl();
|
||||||
|
clone.setSpatial(clonedNode);
|
||||||
|
|
||||||
|
clone.skeleton = ctrl.getSkeleton();
|
||||||
|
Mesh[] meshes = new Mesh[targets.length];
|
||||||
|
for (int i = 0; i < meshes.length; i++) {
|
||||||
|
meshes[i] = ((Geometry) clonedNode.getChild(i)).getMesh();
|
||||||
|
}
|
||||||
|
for (int i = meshes.length; i < clonedNode.getQuantity(); i++) {
|
||||||
|
// go through attachment nodes, apply them to correct bone
|
||||||
|
Spatial child = clonedNode.getChild(i);
|
||||||
|
if (child instanceof Node) {
|
||||||
|
Node clonedAttachNode = (Node) child;
|
||||||
|
Bone originalBone = (Bone) clonedAttachNode.getUserData("AttachedBone");
|
||||||
|
|
||||||
|
if (originalBone != null) {
|
||||||
|
Bone clonedBone = clone.skeleton.getBone(originalBone.getName());
|
||||||
|
|
||||||
|
clonedAttachNode.setUserData("AttachedBone", clonedBone);
|
||||||
|
clonedBone.setAttachmentsNode(clonedAttachNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clone.targets = meshes;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param boneName the name of the bone
|
||||||
|
* @return the node attached to this bone
|
||||||
|
*/
|
||||||
|
public Node getAttachmentsNode(String boneName) {
|
||||||
|
Bone b = skeleton.getBone(boneName);
|
||||||
|
if (b == null) {
|
||||||
|
throw new IllegalArgumentException("Given bone name does not exist "
|
||||||
|
+ "in the skeleton.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Node n = b.getAttachmentsNode();
|
||||||
|
Node model = (Node) spatial;
|
||||||
|
model.attachChild(n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Skeleton getSkeleton() {
|
||||||
|
return skeleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkeleton(Skeleton skeleton) {
|
||||||
|
this.skeleton = skeleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mesh[] getTargets() {
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargets(Mesh[] targets) {
|
||||||
|
this.targets = targets;
|
||||||
|
}
|
||||||
|
|
||||||
private void softwareSkinUpdate(Mesh mesh, Matrix4f[] offsetMatrices) {
|
private void softwareSkinUpdate(Mesh mesh, Matrix4f[] offsetMatrices) {
|
||||||
int maxWeightsPerVert = mesh.getMaxNumWeights();
|
int maxWeightsPerVert = mesh.getMaxNumWeights();
|
||||||
if (maxWeightsPerVert <= 0)
|
if (maxWeightsPerVert <= 0)
|
||||||
@ -186,79 +279,6 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
|
|||||||
// mesh.updateBound();
|
// mesh.updateBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
final void reset() {
|
|
||||||
resetToBind();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void controlRender(RenderManager rm, ViewPort vp) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Control cloneForSpatial(Spatial spatial) {
|
|
||||||
Node clonedNode = (Node) spatial;
|
|
||||||
AnimControl ctrl = spatial.getControl(AnimControl.class);
|
|
||||||
SkeletonControl clone = new SkeletonControl();
|
|
||||||
clone.setSpatial(clonedNode);
|
|
||||||
|
|
||||||
clone.skeleton = ctrl.getSkeleton();
|
|
||||||
Mesh[] meshes = new Mesh[targets.length];
|
|
||||||
for (int i = 0; i < meshes.length; i++) {
|
|
||||||
meshes[i] = ((Geometry) clonedNode.getChild(i)).getMesh();
|
|
||||||
}
|
|
||||||
for (int i = meshes.length; i < clonedNode.getQuantity(); i++) {
|
|
||||||
// go through attachment nodes, apply them to correct bone
|
|
||||||
Spatial child = clonedNode.getChild(i);
|
|
||||||
if (child instanceof Node) {
|
|
||||||
Node clonedAttachNode = (Node) child;
|
|
||||||
Bone originalBone = (Bone) clonedAttachNode.getUserData("AttachedBone");
|
|
||||||
|
|
||||||
if (originalBone != null) {
|
|
||||||
Bone clonedBone = clone.skeleton.getBone(originalBone.getName());
|
|
||||||
|
|
||||||
clonedAttachNode.setUserData("AttachedBone", clonedBone);
|
|
||||||
clonedBone.setAttachmentsNode(clonedAttachNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clone.targets = meshes;
|
|
||||||
return clone;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param boneName the name of the bone
|
|
||||||
* @return the node attached to this bone
|
|
||||||
*/
|
|
||||||
public Node getAttachmentsNode(String boneName) {
|
|
||||||
Bone b = skeleton.getBone(boneName);
|
|
||||||
if (b == null) {
|
|
||||||
throw new IllegalArgumentException("Given bone name does not exist "
|
|
||||||
+ "in the skeleton.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Node n = b.getAttachmentsNode();
|
|
||||||
Node model = (Node) spatial;
|
|
||||||
model.attachChild(n);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Skeleton getSkeleton() {
|
|
||||||
return skeleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSkeleton(Skeleton skeleton) {
|
|
||||||
this.skeleton = skeleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mesh[] getTargets() {
|
|
||||||
return targets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTargets(Mesh[] targets) {
|
|
||||||
this.targets = targets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
super.write(ex);
|
super.write(ex);
|
||||||
|
@ -435,7 +435,6 @@ public class RenderManager {
|
|||||||
for (int i = 0; i < gl.size(); i++) {
|
for (int i = 0; i < gl.size(); i++) {
|
||||||
renderGeometry(gl.get(i));
|
renderGeometry(gl.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user