use of org.terasology.rendering.assets.animation.MeshAnimationFrame in project Terasology by MovingBlocks.
the class SkeletonRenderer method updateSkeletalMeshOfEntity.
private void updateSkeletalMeshOfEntity(EntityRef entity, float delta) {
SkeletalMeshComponent skeletalMeshComp = entity.getComponent(SkeletalMeshComponent.class);
if (skeletalMeshComp.animation == null && skeletalMeshComp.animationPool != null) {
skeletalMeshComp.animation = randomAnimationData(skeletalMeshComp, random);
}
if (skeletalMeshComp.animation == null) {
return;
}
if (skeletalMeshComp.animation.getFrameCount() < 1) {
return;
}
skeletalMeshComp.animationTime += delta * skeletalMeshComp.animationRate;
float animationDuration = getDurationOfAnimation(skeletalMeshComp);
while (skeletalMeshComp.animationTime >= animationDuration) {
MeshAnimation newAnimation;
if (!skeletalMeshComp.loop) {
newAnimation = null;
} else {
newAnimation = randomAnimationData(skeletalMeshComp, random);
}
if (newAnimation == null) {
MeshAnimation finishedAnimation = skeletalMeshComp.animation;
skeletalMeshComp.animationTime = animationDuration;
MeshAnimationFrame frame = skeletalMeshComp.animation.getFrame(skeletalMeshComp.animation.getFrameCount() - 1);
updateSkeleton(skeletalMeshComp, frame, frame, 1.0f);
// Set animation to null so that AnimEndEvent fires only once
skeletalMeshComp.animation = null;
entity.saveComponent(skeletalMeshComp);
entity.send(new AnimEndEvent(finishedAnimation));
return;
}
skeletalMeshComp.animationTime -= animationDuration;
if (skeletalMeshComp.animationTime < 0) {
// In case the float calculation wasn't exact:
skeletalMeshComp.animationTime = 0;
}
skeletalMeshComp.animation = newAnimation;
animationDuration = getDurationOfAnimation(skeletalMeshComp);
}
float framePos = skeletalMeshComp.animationTime / skeletalMeshComp.animation.getTimePerFrame();
int frameAId = (int) framePos;
int frameBId = frameAId + 1;
if (frameBId >= skeletalMeshComp.animation.getFrameCount()) {
// In case the float calcuation wasn't exact:
frameBId = skeletalMeshComp.animation.getFrameCount() - 1;
}
MeshAnimationFrame frameA = skeletalMeshComp.animation.getFrame(frameAId);
MeshAnimationFrame frameB = skeletalMeshComp.animation.getFrame(frameBId);
updateSkeleton(skeletalMeshComp, frameA, frameB, framePos - frameAId);
entity.saveComponent(skeletalMeshComp);
}
use of org.terasology.rendering.assets.animation.MeshAnimationFrame in project Terasology by MovingBlocks.
the class MD5AnimationLoader method createAnimation.
private MeshAnimationData createAnimation(MD5 md5) {
List<String> boneNames = Lists.newArrayListWithCapacity(md5.numJoints);
TIntList boneParents = new TIntArrayList(md5.numJoints);
for (int i = 0; i < md5.numJoints; ++i) {
boneNames.add(md5.joints[i].name);
boneParents.add(md5.joints[i].parent);
}
float timePerFrame = 1.0f / md5.frameRate;
List<MeshAnimationFrame> frames = Lists.newArrayList();
for (int frameIndex = 0; frameIndex < md5.numFrames; ++frameIndex) {
MD5Frame frame = md5.frames[frameIndex];
List<Vector3f> positions = Lists.newArrayListWithExpectedSize(md5.numJoints);
List<Vector3f> rawRotations = Lists.newArrayListWithExpectedSize(md5.numJoints);
for (int i = 0; i < md5.numJoints; ++i) {
positions.add(new Vector3f(md5.baseFramePosition[i]));
rawRotations.add(new Vector3f(md5.baseFrameOrientation[i]));
}
for (int jointIndex = 0; jointIndex < md5.numJoints; ++jointIndex) {
int compIndex = 0;
if ((md5.joints[jointIndex].flags & POSITION_X_FLAG) != 0) {
positions.get(jointIndex).x = frame.components[md5.joints[jointIndex].startIndex + compIndex];
compIndex++;
}
if ((md5.joints[jointIndex].flags & POSITION_Y_FLAG) != 0) {
positions.get(jointIndex).y = frame.components[md5.joints[jointIndex].startIndex + compIndex];
compIndex++;
}
if ((md5.joints[jointIndex].flags & POSITION_Z_FLAG) != 0) {
positions.get(jointIndex).z = frame.components[md5.joints[jointIndex].startIndex + compIndex];
compIndex++;
}
if ((md5.joints[jointIndex].flags & ORIENTATION_X_FLAG) != 0) {
rawRotations.get(jointIndex).x = frame.components[md5.joints[jointIndex].startIndex + compIndex];
compIndex++;
}
if ((md5.joints[jointIndex].flags & ORIENTATION_Y_FLAG) != 0) {
rawRotations.get(jointIndex).y = frame.components[md5.joints[jointIndex].startIndex + compIndex];
compIndex++;
}
if ((md5.joints[jointIndex].flags & ORIENTATION_Z_FLAG) != 0) {
rawRotations.get(jointIndex).z = frame.components[md5.joints[jointIndex].startIndex + compIndex];
}
}
List<Quat4f> rotations = rawRotations.stream().map(rot -> MD5ParserCommon.completeQuat4f(rot.x, rot.y, rot.z)).collect(Collectors.toCollection(ArrayList::new));
// Rotate just the root bone to correct for coordinate system differences
rotations.set(0, MD5ParserCommon.correctQuat4f(rotations.get(0)));
positions.set(0, MD5ParserCommon.correctOffset(positions.get(0)));
frames.add(new MeshAnimationFrame(positions, rotations));
}
AABB aabb = AABB.createEncompassing(Arrays.asList(md5.bounds));
return new MeshAnimationData(boneNames, boneParents, frames, timePerFrame, aabb);
}
Aggregations