Search in sources :

Example 6 with AnimChannel

use of com.jme3.animation.AnimChannel in project jmonkeyengine by jMonkeyEngine.

the class SimulationNode method simulateSkeleton.

/**
     * Simulates the bone node.
     */
private void simulateSkeleton() {
    LOGGER.fine("Simulating skeleton.");
    Set<Long> alteredOmas = new HashSet<Long>();
    if (animations != null) {
        TempVars vars = TempVars.get();
        AnimChannel animChannel = animControl.createChannel();
        for (Animation animation : animations) {
            float[] animationTimeBoundaries = this.computeAnimationTimeBoundaries(animation);
            int maxFrame = (int) animationTimeBoundaries[0];
            float maxTime = animationTimeBoundaries[1];
            Map<Integer, VirtualTrack> tracks = new HashMap<Integer, VirtualTrack>();
            for (int frame = 0; frame < maxFrame; ++frame) {
                // this MUST be done here, otherwise setting next frame of animation will
                // lead to possible errors
                this.reset();
                // first set proper time for all bones in all the tracks ...
                for (Track track : animation.getTracks()) {
                    float time = ((BoneTrack) track).getTimes()[frame];
                    track.setTime(time, 1, animControl, animChannel, vars);
                    skeleton.updateWorldVectors();
                }
                // ... and then apply constraints from the root bone to the last child ...
                Set<Long> applied = new HashSet<Long>();
                for (Bone rootBone : skeleton.getRoots()) {
                    // ignore the 0-indexed bone
                    if (skeleton.getBoneIndex(rootBone) > 0) {
                        this.applyConstraints(rootBone, alteredOmas, applied, frame, new Stack<Bone>());
                    }
                }
                // ... add virtual tracks if neccessary, for bones that were altered but had no tracks before ...
                for (Long boneOMA : alteredOmas) {
                    BoneContext boneContext = blenderContext.getBoneContext(boneOMA);
                    int boneIndex = skeleton.getBoneIndex(boneContext.getBone());
                    if (!tracks.containsKey(boneIndex)) {
                        tracks.put(boneIndex, new VirtualTrack(boneContext.getBone().getName(), maxFrame, maxTime));
                    }
                }
                alteredOmas.clear();
                // ... and fill in another frame in the result track
                for (Entry<Integer, VirtualTrack> trackEntry : tracks.entrySet()) {
                    Bone bone = skeleton.getBone(trackEntry.getKey());
                    Transform startTransform = boneStartTransforms.get(bone);
                    // track contains differences between the frame position and bind positions of bones/spatials
                    Vector3f bonePositionDifference = bone.getLocalPosition().subtract(startTransform.getTranslation());
                    Quaternion boneRotationDifference = startTransform.getRotation().inverse().mult(bone.getLocalRotation()).normalizeLocal();
                    Vector3f boneScaleDifference = bone.getLocalScale().divide(startTransform.getScale());
                    trackEntry.getValue().setTransform(frame, new Transform(bonePositionDifference, boneRotationDifference, boneScaleDifference));
                }
            }
            for (Entry<Integer, VirtualTrack> trackEntry : tracks.entrySet()) {
                Track newTrack = trackEntry.getValue().getAsBoneTrack(trackEntry.getKey());
                if (newTrack != null) {
                    boolean trackReplaced = false;
                    for (Track track : animation.getTracks()) {
                        if (((BoneTrack) track).getTargetBoneIndex() == trackEntry.getKey().intValue()) {
                            animation.removeTrack(track);
                            animation.addTrack(newTrack);
                            trackReplaced = true;
                            break;
                        }
                    }
                    if (!trackReplaced) {
                        animation.addTrack(newTrack);
                    }
                }
            }
        }
        vars.release();
        animControl.clearChannels();
        this.reset();
    }
}
Also used : HashMap(java.util.HashMap) Quaternion(com.jme3.math.Quaternion) AnimChannel(com.jme3.animation.AnimChannel) TempVars(com.jme3.util.TempVars) BoneContext(com.jme3.scene.plugins.blender.animations.BoneContext) Vector3f(com.jme3.math.Vector3f) Animation(com.jme3.animation.Animation) Bone(com.jme3.animation.Bone) Transform(com.jme3.math.Transform) SpatialTrack(com.jme3.animation.SpatialTrack) BoneTrack(com.jme3.animation.BoneTrack) Track(com.jme3.animation.Track) HashSet(java.util.HashSet)

Example 7 with AnimChannel

use of com.jme3.animation.AnimChannel 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);
    }
}
Also used : Spatial(com.jme3.scene.Spatial) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f)

Example 8 with AnimChannel

use of com.jme3.animation.AnimChannel in project jmonkeyengine by jMonkeyEngine.

the class TestModelExportingCloning method simpleInitApp.

@Override
public void simpleInitApp() {
    cam.setLocation(new Vector3f(10f, 3f, 40f));
    cam.lookAtDirection(Vector3f.UNIT_Z.negate(), Vector3f.UNIT_Y);
    DirectionalLight dl = new DirectionalLight();
    dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal());
    dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
    rootNode.addLight(dl);
    AnimControl control;
    AnimChannel channel;
    Spatial originalModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
    control = originalModel.getControl(AnimControl.class);
    channel = control.createChannel();
    channel.setAnim("Walk");
    rootNode.attachChild(originalModel);
    Spatial clonedModel = originalModel.clone();
    clonedModel.move(10, 0, 0);
    control = clonedModel.getControl(AnimControl.class);
    channel = control.createChannel();
    channel.setAnim("push");
    rootNode.attachChild(clonedModel);
    Spatial exportedModel = BinaryExporter.saveAndLoad(assetManager, originalModel);
    exportedModel.move(20, 0, 0);
    control = exportedModel.getControl(AnimControl.class);
    channel = control.createChannel();
    channel.setAnim("pull");
    rootNode.attachChild(exportedModel);
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) Spatial(com.jme3.scene.Spatial) Vector3f(com.jme3.math.Vector3f) DirectionalLight(com.jme3.light.DirectionalLight) AnimChannel(com.jme3.animation.AnimChannel) AnimControl(com.jme3.animation.AnimControl)

Aggregations

Vector3f (com.jme3.math.Vector3f)8 Quaternion (com.jme3.math.Quaternion)5 AnimChannel (com.jme3.animation.AnimChannel)4 AnimControl (com.jme3.animation.AnimControl)4 DirectionalLight (com.jme3.light.DirectionalLight)3 Spatial (com.jme3.scene.Spatial)3 BulletAppState (com.jme3.bullet.BulletAppState)2 KinematicRagdollControl (com.jme3.bullet.control.KinematicRagdollControl)2 Material (com.jme3.material.Material)2 ColorRGBA (com.jme3.math.ColorRGBA)2 Node (com.jme3.scene.Node)2 SkeletonDebugger (com.jme3.scene.debug.SkeletonDebugger)2 Animation (com.jme3.animation.Animation)1 Bone (com.jme3.animation.Bone)1 BoneTrack (com.jme3.animation.BoneTrack)1 SpatialTrack (com.jme3.animation.SpatialTrack)1 Track (com.jme3.animation.Track)1 SphereCollisionShape (com.jme3.bullet.collision.shapes.SphereCollisionShape)1 RigidBodyControl (com.jme3.bullet.control.RigidBodyControl)1 BinaryExporter (com.jme3.export.binary.BinaryExporter)1