Search in sources :

Example 1 with MeshAnimation

use of org.terasology.engine.rendering.assets.animation.MeshAnimation in project Terasology by MovingBlocks.

the class SkeletonRenderer method renderOpaque.

@Override
public void renderOpaque() {
    Vector3fc cameraPosition = worldRenderer.getActiveCamera().getPosition();
    Quaternionf worldRot = new Quaternionf();
    Vector3f worldPos = new Vector3f();
    Quaternionf inverseWorldRot = new Quaternionf();
    FloatBuffer tempMatrixBuffer44 = BufferUtils.createFloatBuffer(16);
    FloatBuffer tempMatrixBuffer33 = BufferUtils.createFloatBuffer(12);
    for (EntityRef entity : entityManager.getEntitiesWith(SkeletalMeshComponent.class, LocationComponent.class)) {
        SkeletalMeshComponent skeletalMesh = entity.getComponent(SkeletalMeshComponent.class);
        if (skeletalMesh.mesh == null || skeletalMesh.material == null || skeletalMesh.boneEntities == null || !skeletalMesh.material.isRenderable()) {
            continue;
        }
        AABBf aabb;
        MeshAnimation animation = skeletalMesh.animation;
        if (animation != null) {
            aabb = animation.getAabb();
        } else {
            aabb = skeletalMesh.mesh.getStaticAabb();
        }
        LocationComponent location = entity.getComponent(LocationComponent.class);
        location.getWorldRotation(worldRot);
        worldRot.invert(inverseWorldRot);
        location.getWorldPosition(worldPos);
        float worldScale = location.getWorldScale();
        aabb = aabb.transform(new Matrix4f().translationRotateScale(worldPos, worldRot, worldScale), new AABBf());
        // Scale bounding box for skeletalMesh.
        Vector3f scale = skeletalMesh.scale;
        Vector3f aabbCenter = aabb.center(new Vector3f());
        Vector3f scaledExtents = aabb.extent(new Vector3f()).mul(scale.x(), scale.y(), scale.z());
        aabb = new AABBf(aabbCenter, aabbCenter).expand(scaledExtents);
        if (!worldRenderer.getActiveCamera().hasInSight(aabb)) {
            continue;
        }
        skeletalMesh.material.enable();
        skeletalMesh.material.setFloat("sunlight", 1.0f, true);
        skeletalMesh.material.setFloat("blockLight", 1.0f, true);
        skeletalMesh.material.setFloat3("colorOffset", skeletalMesh.color.rf(), skeletalMesh.color.gf(), skeletalMesh.color.bf(), true);
        skeletalMesh.material.setMatrix4("projectionMatrix", worldRenderer.getActiveCamera().getProjectionMatrix());
        skeletalMesh.material.bindTextures();
        Vector3f worldPositionCameraSpace = new Vector3f();
        worldPos.sub(cameraPosition, worldPositionCameraSpace);
        worldPositionCameraSpace.y += skeletalMesh.heightOffset;
        Matrix4f matrixCameraSpace = new Matrix4f().translationRotateScale(worldPositionCameraSpace, worldRot, worldScale);
        Matrix4f modelViewMatrix = worldRenderer.getActiveCamera().getViewMatrix().mul(matrixCameraSpace, new Matrix4f());
        modelViewMatrix.get(tempMatrixBuffer44);
        skeletalMesh.material.setMatrix4("modelViewMatrix", tempMatrixBuffer44, true);
        modelViewMatrix.normal(new Matrix3f()).get(tempMatrixBuffer33);
        skeletalMesh.material.setMatrix3("normalMatrix", tempMatrixBuffer33, true);
        skeletalMesh.material.setFloat("sunlight", worldRenderer.getMainLightIntensityAt(worldPos), true);
        skeletalMesh.material.setFloat("blockLight", worldRenderer.getBlockLightIntensityAt(worldPos), true);
        Matrix4f[] boneTransforms = new Matrix4f[skeletalMesh.mesh.getBones().size()];
        for (Bone bone : skeletalMesh.mesh.getBones()) {
            EntityRef boneEntity = skeletalMesh.boneEntities.get(bone.getName());
            if (boneEntity == null) {
                boneEntity = EntityRef.NULL;
            }
            LocationComponent boneLocation = boneEntity.getComponent(LocationComponent.class);
            if (boneLocation != null) {
                Matrix4f boneTransform = new Matrix4f();
                boneLocation.getRelativeTransform(boneTransform, entity);
                boneTransform.mul(bone.getInverseBindMatrix());
                boneTransforms[bone.getIndex()] = boneTransform.transpose();
            } else {
                logger.warn("Unable to resolve bone \"{}\"", bone.getName());
                boneTransforms[bone.getIndex()] = new Matrix4f();
            }
        }
        ((OpenGLSkeletalMesh) skeletalMesh.mesh).setScaleTranslate(skeletalMesh.scale, skeletalMesh.translate);
        ((OpenGLSkeletalMesh) skeletalMesh.mesh).render(Arrays.asList(boneTransforms));
    }
}
Also used : Quaternionf(org.joml.Quaternionf) FloatBuffer(java.nio.FloatBuffer) LocationComponent(org.terasology.engine.logic.location.LocationComponent) Vector3fc(org.joml.Vector3fc) Matrix4f(org.joml.Matrix4f) AABBf(org.terasology.joml.geom.AABBf) Matrix3f(org.joml.Matrix3f) OpenGLSkeletalMesh(org.terasology.engine.rendering.opengl.OpenGLSkeletalMesh) Vector3f(org.joml.Vector3f) MeshAnimation(org.terasology.engine.rendering.assets.animation.MeshAnimation) Bone(org.terasology.engine.rendering.assets.skeletalmesh.Bone) EntityRef(org.terasology.engine.entitySystem.entity.EntityRef)

Example 2 with MeshAnimation

use of org.terasology.engine.rendering.assets.animation.MeshAnimation 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.mesh == null) {
        return;
    }
    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 if (skeletalMeshComp.animationPool != null && !skeletalMeshComp.animationPool.isEmpty()) {
            newAnimation = randomAnimationData(skeletalMeshComp, random);
        } else {
            newAnimation = skeletalMeshComp.animation;
        }
        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);
}
Also used : MeshAnimationFrame(org.terasology.engine.rendering.assets.animation.MeshAnimationFrame) MeshAnimation(org.terasology.engine.rendering.assets.animation.MeshAnimation)

Aggregations

MeshAnimation (org.terasology.engine.rendering.assets.animation.MeshAnimation)2 FloatBuffer (java.nio.FloatBuffer)1 Matrix3f (org.joml.Matrix3f)1 Matrix4f (org.joml.Matrix4f)1 Quaternionf (org.joml.Quaternionf)1 Vector3f (org.joml.Vector3f)1 Vector3fc (org.joml.Vector3fc)1 EntityRef (org.terasology.engine.entitySystem.entity.EntityRef)1 LocationComponent (org.terasology.engine.logic.location.LocationComponent)1 MeshAnimationFrame (org.terasology.engine.rendering.assets.animation.MeshAnimationFrame)1 Bone (org.terasology.engine.rendering.assets.skeletalmesh.Bone)1 OpenGLSkeletalMesh (org.terasology.engine.rendering.opengl.OpenGLSkeletalMesh)1 AABBf (org.terasology.joml.geom.AABBf)1