glaucomardano

Some fixes for AnimationFactory.java

Oct 8th, 2013
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 51.42 KB | None | 0 0
  1. # This patch file was generated by NetBeans IDE
  2. # Following Index: paths are relative to: D:\SHARE\jMonkeyProjects\trunk\engine\src
  3. # This patch can be applied using context Tools: Patch action on respective folder.
  4. # It uses platform neutral UTF-8 encoding and \n newlines.
  5. # Above lines and this line are ignored by the patching process.
  6. Index: core/com/jme3/animation/AnimationBuilder.java
  7. --- core/com/jme3/animation/AnimationBuilder.java Nenhuma Revisão de Base
  8. +++ core/com/jme3/animation/AnimationBuilder.java Novo Localmente
  9. @@ -0,0 +1,496 @@
  10. +/*
  11. + * Copyright (c) 2009-2012 jMonkeyEngine
  12. + * All rights reserved.
  13. + *
  14. + * Redistribution and use in source and binary forms, with or without
  15. + * modification, are permitted provided that the following conditions are
  16. + * met:
  17. + *
  18. + * * Redistributions of source code must retain the above copyright
  19. + *   notice, this list of conditions and the following disclaimer.
  20. + *
  21. + * * Redistributions in binary form must reproduce the above copyright
  22. + *   notice, this list of conditions and the following disclaimer in the
  23. + *   documentation and/or other materials provided with the distribution.
  24. + *
  25. + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  26. + *   may be used to endorse or promote products derived from this software
  27. + *   without specific prior written permission.
  28. + *
  29. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  31. + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  32. + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  33. + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  34. + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35. + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36. + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  37. + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  38. + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. + */
  41. +package com.jme3.animation;
  42. +
  43. +import com.jme3.math.FastMath;
  44. +import com.jme3.math.Quaternion;
  45. +import com.jme3.math.Transform;
  46. +import com.jme3.math.Vector3f;
  47. +
  48. +/**
  49. + * A convenience class to easily setup a spatial keyframed animation
  50. + * you can add some keyFrames for a given time or a given keyFrameIndex, for translation rotation and scale.
  51. + * The animationBuilder will then generate an appropriate SpatialAnimation by interpolating values between the keyFrames.
  52. + * <br><br>
  53. + * Usage is : <br>
  54. + * - Create the AnimationBuilder<br>
  55. + * - add some keyFrames<br>
  56. + * - call the build() method that will return new Animation<br>
  57. + * - add the generated Animation to any existing AnimationControl<br>
  58. + * <br><br>
  59. + * Note that the first keyFrame (index 0) is defaulted with the identy transforms.
  60. + * If you want to change that you have to replace this keyFrame with any transform you want.
  61. + *
  62. + * @author Nehon
  63. + */
  64. +public class AnimationBuilder {
  65. +
  66. +    /**
  67. +     * step for splitting rotation that have a n angle above PI/2
  68. +     */
  69. +    private final static float EULER_STEP = FastMath.QUARTER_PI * 3;
  70. +
  71. +    /**
  72. +     * enum to determine the type of interpolation
  73. +     */
  74. +    private enum Type {
  75. +
  76. +        Translation, Rotation, Scale;
  77. +    }
  78. +
  79. +    /**
  80. +     * Inner Rotation type class to keep track on a rotation Euler angle
  81. +     */
  82. +    protected class Rotation {
  83. +
  84. +        /**
  85. +         * The rotation Quaternion
  86. +         */
  87. +        Quaternion rotation = new Quaternion();
  88. +        /**
  89. +         * This rotation expressed in Euler angles
  90. +         */
  91. +        Vector3f eulerAngles = new Vector3f();
  92. +        /**
  93. +         * the index of the parent key frame is this keyFrame is a splitted rotation
  94. +         */
  95. +        int masterKeyFrame = -1;
  96. +
  97. +        public Rotation() {
  98. +            rotation.loadIdentity();
  99. +        }
  100. +
  101. +        void set(Quaternion rot) {
  102. +            rotation.set(rot);
  103. +            float[] a = new float[3];
  104. +            rotation.toAngles(a);
  105. +            eulerAngles.set(a[0], a[1], a[2]);
  106. +        }
  107. +
  108. +        void set(float x, float y, float z) {
  109. +            float[] a = {x, y, z};
  110. +            rotation.fromAngles(a);
  111. +            eulerAngles.set(x, y, z);
  112. +        }
  113. +    }
  114. +    /**
  115. +     * Name of the animation
  116. +     */
  117. +    protected String name;
  118. +    /**
  119. +     * frames per seconds
  120. +     */
  121. +    protected int fps;
  122. +    /**
  123. +     * Animation duration in seconds
  124. +     */
  125. +    protected float duration;
  126. +    /**
  127. +     * total number of frames
  128. +     */
  129. +    protected int totalFrames;
  130. +    /**
  131. +     * time per frame
  132. +     */
  133. +    protected float tpf;
  134. +    /**
  135. +     * Time array for this animation
  136. +     */
  137. +    protected float[] times;
  138. +    /**
  139. +     * Translation array for this animation
  140. +     */
  141. +    protected Vector3f[] translations;
  142. +    /**
  143. +     * rotation array for this animation
  144. +     */
  145. +    protected Quaternion[] rotations;
  146. +    /**
  147. +     * scales array for this animation
  148. +     */
  149. +    protected Vector3f[] scales;
  150. +    /**
  151. +     * The map of keyFrames to compute the animation. The key is the index of the frame
  152. +     */
  153. +    protected Vector3f[] keyFramesTranslation;
  154. +    protected Vector3f[] keyFramesScale;
  155. +    protected Rotation[] keyFramesRotation;
  156. +
  157. +    /**
  158. +     * Creates an AnimationBuilder
  159. +     * @param duration the desired duration for the resulting animation
  160. +     * @param name the name of the resulting animation
  161. +     */
  162. +    public AnimationBuilder(float duration, String name) {
  163. +        this(duration, name, 30);
  164. +    }
  165. +
  166. +    /**
  167. +     * Creates an AnimationBuilder
  168. +     * @param duration the desired duration for the resulting animation
  169. +     * @param name the name of the resulting animation
  170. +     * @param fps the number of frames per second for this animation (default is 30)
  171. +     */
  172. +    public AnimationBuilder(float duration, String name, int fps) {
  173. +        this.name = name;
  174. +        this.duration = duration;
  175. +        this.fps = fps;
  176. +        totalFrames = (int) (fps * duration) + 1;
  177. +        tpf = 1 / (float) fps;
  178. +        times = new float[totalFrames];
  179. +        translations = new Vector3f[totalFrames];
  180. +        rotations = new Quaternion[totalFrames];
  181. +        scales = new Vector3f[totalFrames];
  182. +        keyFramesTranslation = new Vector3f[totalFrames];
  183. +        keyFramesTranslation[0] = new Vector3f();
  184. +        keyFramesScale = new Vector3f[totalFrames];
  185. +        keyFramesScale[0] = new Vector3f(1, 1, 1);
  186. +        keyFramesRotation = new Rotation[totalFrames];
  187. +        keyFramesRotation[0] = new Rotation();
  188. +
  189. +    }
  190. +
  191. +    /**
  192. +     * Adds a key frame for the given Transform at the given time
  193. +     * @param time the time at which the keyFrame must be inserted
  194. +     * @param transform the transforms to use for this keyFrame
  195. +     */
  196. +    public void addTimeTransform(float time, Transform transform) {
  197. +        addKeyFrameTransform((int) (time / tpf), transform);
  198. +    }
  199. +
  200. +    /**
  201. +     * Adds a key frame for the given Transform at the given keyFrame index
  202. +     * @param keyFrameIndex the index at which the keyFrame must be inserted
  203. +     * @param transform the transforms to use for this keyFrame
  204. +     */
  205. +    public void addKeyFrameTransform(int keyFrameIndex, Transform transform) {
  206. +        addKeyFrameTranslation(keyFrameIndex, transform.getTranslation());
  207. +        addKeyFrameScale(keyFrameIndex, transform.getScale());
  208. +        addKeyFrameRotation(keyFrameIndex, transform.getRotation());
  209. +    }
  210. +
  211. +    /**
  212. +     * Adds a key frame for the given translation at the given time
  213. +     * @param time the time at which the keyFrame must be inserted
  214. +     * @param translation the translation to use for this keyFrame
  215. +     */
  216. +    public void addTimeTranslation(float time, Vector3f translation) {
  217. +        addKeyFrameTranslation((int) (time / tpf), translation);
  218. +    }
  219. +
  220. +    /**
  221. +     * Adds a key frame for the given translation at the given keyFrame index
  222. +     * @param keyFrameIndex the index at which the keyFrame must be inserted
  223. +     * @param translation the translation to use for this keyFrame
  224. +     */
  225. +    public void addKeyFrameTranslation(int keyFrameIndex, Vector3f translation) {
  226. +        Vector3f t = getTranslationForFrame(keyFrameIndex);
  227. +        t.set(translation);
  228. +    }
  229. +
  230. +    /**
  231. +     * Adds a key frame for the given rotation at the given time<br>
  232. +     * This can't be used if the interpolated angle is higher than PI (180°)<br>
  233. +     * Use {@link #addTimeRotationAngles(float time, float x, float y, float z)}  instead that uses Euler angles rotations.<br>     *
  234. +     * @param time the time at which the keyFrame must be inserted
  235. +     * @param rotation the rotation Quaternion to use for this keyFrame
  236. +     * @see #addTimeRotationAngles(float time, float x, float y, float z)
  237. +     */
  238. +    public void addTimeRotation(float time, Quaternion rotation) {
  239. +        addKeyFrameRotation((int) (time / tpf), rotation);
  240. +    }
  241. +
  242. +    /**
  243. +     * Adds a key frame for the given rotation at the given keyFrame index<br>
  244. +     * This can't be used if the interpolated angle is higher than PI (180°)<br>
  245. +     * Use {@link #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)} instead that uses Euler angles rotations.
  246. +     * @param keyFrameIndex the index at which the keyFrame must be inserted
  247. +     * @param rotation the rotation Quaternion to use for this keyFrame
  248. +     * @see #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)
  249. +     */
  250. +    public void addKeyFrameRotation(int keyFrameIndex, Quaternion rotation) {
  251. +        Rotation r = getRotationForFrame(keyFrameIndex);
  252. +        r.set(rotation);
  253. +    }
  254. +
  255. +    /**
  256. +     * Adds a key frame for the given rotation at the given time.<br>
  257. +     * Rotation is expressed by Euler angles values in radians.<br>
  258. +     * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
  259. +     * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
  260. +     *
  261. +     * @param time the time at which the keyFrame must be inserted
  262. +     * @param x the rotation around the x axis (aka yaw) in radians
  263. +     * @param y the rotation around the y axis (aka roll) in radians
  264. +     * @param z the rotation around the z axis (aka pitch) in radians
  265. +     */
  266. +    public void addTimeRotationAngles(float time, float x, float y, float z) {
  267. +        addKeyFrameRotationAngles((int) (time / tpf), x, y, z);
  268. +    }
  269. +
  270. +    /**
  271. +     * Adds a key frame for the given rotation at the given key frame index.<br>
  272. +     * Rotation is expressed by Euler angles values in radians.<br>
  273. +     * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
  274. +     * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
  275. +     *
  276. +     * @param keyFrameIndex the index at which the keyFrame must be inserted
  277. +     * @param x the rotation around the x axis (aka yaw) in radians
  278. +     * @param y the rotation around the y axis (aka roll) in radians
  279. +     * @param z the rotation around the z axis (aka pitch) in radians
  280. +     */
  281. +    public void addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z) {
  282. +        Rotation r = getRotationForFrame(keyFrameIndex);
  283. +        r.set(x, y, z);
  284. +
  285. +        // if the delta of euler angles is higher than PI, we create intermediate keyframes
  286. +        // since we are using quaternions and slerp for rotation interpolation, we cannot interpolate over an angle higher than PI
  287. +        int prev = getPreviousKeyFrame(keyFrameIndex, keyFramesRotation);
  288. +        if (prev != -1) {
  289. +            //previous rotation keyframe
  290. +            Rotation prevRot = keyFramesRotation[prev];
  291. +            //the maximum delta angle (x,y or z)
  292. +            float delta = Math.max(Math.abs(x - prevRot.eulerAngles.x), Math.abs(y - prevRot.eulerAngles.y));
  293. +            delta = Math.max(delta, Math.abs(z - prevRot.eulerAngles.z));
  294. +            //if delta > PI we have to create intermediates key frames
  295. +            if (delta >= FastMath.PI) {
  296. +                //frames delta
  297. +                int dF = keyFrameIndex - prev;
  298. +                //angle per frame for x,y ,z
  299. +                float dXAngle = (x - prevRot.eulerAngles.x) / (float) dF;
  300. +                float dYAngle = (y - prevRot.eulerAngles.y) / (float) dF;
  301. +                float dZAngle = (z - prevRot.eulerAngles.z) / (float) dF;
  302. +
  303. +                // the keyFrame step
  304. +                int keyStep = (int) (((float) (dF)) / delta * (float) EULER_STEP);
  305. +                // the current keyFrame
  306. +                int cursor = prev + keyStep;
  307. +                while (cursor < keyFrameIndex) {
  308. +                    //for each step we create a new rotation by interpolating the angles
  309. +                    Rotation dr = getRotationForFrame(cursor);
  310. +                    dr.masterKeyFrame = keyFrameIndex;
  311. +                    dr.set(prevRot.eulerAngles.x + cursor * dXAngle, prevRot.eulerAngles.y + cursor * dYAngle, prevRot.eulerAngles.z + cursor * dZAngle);
  312. +                    cursor += keyStep;
  313. +                }
  314. +
  315. +            }
  316. +        }
  317. +
  318. +    }
  319. +
  320. +    /**
  321. +     * Adds a key frame for the given scale at the given time
  322. +     * @param time the time at which the keyFrame must be inserted
  323. +     * @param scale the scale to use for this keyFrame
  324. +     */
  325. +    public void addTimeScale(float time, Vector3f scale) {
  326. +        addKeyFrameScale((int) (time / tpf), scale);
  327. +    }
  328. +
  329. +    /**
  330. +     * Adds a key frame for the given scale at the given keyFrame index
  331. +     * @param keyFrameIndex the index at which the keyFrame must be inserted
  332. +     * @param scale the scale to use for this keyFrame
  333. +     */
  334. +    public void addKeyFrameScale(int keyFrameIndex, Vector3f scale) {
  335. +        Vector3f s = getScaleForFrame(keyFrameIndex);
  336. +        s.set(scale);
  337. +    }
  338. +
  339. +    /**
  340. +     * returns the translation for a given frame index
  341. +     * creates the translation if it doesn't exists
  342. +     * @param keyFrameIndex index
  343. +     * @return the translation
  344. +     */
  345. +    private Vector3f getTranslationForFrame(int keyFrameIndex) {
  346. +        if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
  347. +            throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
  348. +        }
  349. +        Vector3f v = keyFramesTranslation[keyFrameIndex];
  350. +        if (v == null) {
  351. +            v = new Vector3f();
  352. +            keyFramesTranslation[keyFrameIndex] = v;
  353. +        }
  354. +        return v;
  355. +    }
  356. +
  357. +    /**
  358. +     * returns the scale for a given frame index
  359. +     * creates the scale if it doesn't exists
  360. +     * @param keyFrameIndex index
  361. +     * @return the scale
  362. +     */
  363. +    private Vector3f getScaleForFrame(int keyFrameIndex) {
  364. +        if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
  365. +            throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
  366. +        }
  367. +        Vector3f v = keyFramesScale[keyFrameIndex];
  368. +        if (v == null) {
  369. +            v = new Vector3f();
  370. +            keyFramesScale[keyFrameIndex] = v;
  371. +        }
  372. +        return v;
  373. +    }
  374. +
  375. +    /**
  376. +     * returns the rotation for a given frame index
  377. +     * creates the rotation if it doesn't exists
  378. +     * @param keyFrameIndex index
  379. +     * @return the rotation
  380. +     */
  381. +    private Rotation getRotationForFrame(int keyFrameIndex) {
  382. +        if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
  383. +            throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
  384. +        }
  385. +        Rotation v = keyFramesRotation[keyFrameIndex];
  386. +        if (v == null) {
  387. +            v = new Rotation();
  388. +            keyFramesRotation[keyFrameIndex] = v;
  389. +        }
  390. +        return v;
  391. +    }
  392. +
  393. +    /**
  394. +     * Creates an Animation based on the keyFrames previously added to the helper.
  395. +     * @return the generated animation
  396. +     */
  397. +    public Animation build() {
  398. +        interpolateTime();
  399. +        interpolate(keyFramesTranslation, Type.Translation);
  400. +        interpolate(keyFramesRotation, Type.Rotation);
  401. +        interpolate(keyFramesScale, Type.Scale);
  402. +
  403. +        SpatialTrack spatialTrack = new SpatialTrack(times, translations, rotations, scales);
  404. +
  405. +        //creating the animation
  406. +        Animation spatialAnimation = new Animation(name, duration);
  407. +        spatialAnimation.setTracks(new SpatialTrack[]{spatialTrack});
  408. +
  409. +        return spatialAnimation;
  410. +    }
  411. +
  412. +    /**
  413. +     * interpolates time values
  414. +     */
  415. +    private void interpolateTime() {
  416. +        for (int i = 0; i < totalFrames; i++) {
  417. +            times[i] = i * tpf;
  418. +        }
  419. +    }
  420. +
  421. +    /**
  422. +     * Interpolates over the key frames for the given keyFrame array and the given type of transform
  423. +     * @param keyFrames the keyFrames array
  424. +     * @param type the type of transforms
  425. +     */
  426. +    private void interpolate(Object[] keyFrames, Type type) {
  427. +        int i = 0;
  428. +        while (i < totalFrames) {
  429. +            //fetching the next keyFrame index transform in the array
  430. +            int key = getNextKeyFrame(i, keyFrames);
  431. +            if (key != -1) {
  432. +                //computing the frame span to interpolate over
  433. +                int span = key - i;
  434. +                //interating over the frames
  435. +                for (int j = i; j <= key; j++) {
  436. +                    // computing interpolation value
  437. +                    float val = (float) (j - i) / (float) span;
  438. +                    //interpolationg depending on the transform type
  439. +                    switch (type) {
  440. +                        case Translation:
  441. +                            translations[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
  442. +                            break;
  443. +                        case Rotation:
  444. +                            Quaternion rot = new Quaternion();
  445. +                            rotations[j] = rot.slerp(((Rotation) keyFrames[i]).rotation, ((Rotation) keyFrames[key]).rotation, val);
  446. +                            break;
  447. +                        case Scale:
  448. +                            scales[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
  449. +                            break;
  450. +                    }
  451. +                }
  452. +                //jumping to the next keyFrame
  453. +                i = key;
  454. +            } else {
  455. +                //No more key frame, filling the array witht he last transform computed.
  456. +                for (int j = i; j < totalFrames; j++) {
  457. +
  458. +                    switch (type) {
  459. +                        case Translation:
  460. +                            translations[j] = ((Vector3f) keyFrames[i]).clone();
  461. +                            break;
  462. +                        case Rotation:
  463. +                            rotations[j] = ((Quaternion) ((Rotation) keyFrames[i]).rotation).clone();
  464. +                            break;
  465. +                        case Scale:
  466. +                            scales[j] = ((Vector3f) keyFrames[i]).clone();
  467. +                            break;
  468. +                    }
  469. +                }
  470. +                //we're done
  471. +                i = totalFrames;
  472. +            }
  473. +        }
  474. +    }
  475. +
  476. +    /**
  477. +     * Get the index of the next keyFrame that as a transform
  478. +     * @param index the start index
  479. +     * @param keyFrames the keyFrames array
  480. +     * @return the index of the next keyFrame
  481. +     */
  482. +    private int getNextKeyFrame(int index, Object[] keyFrames) {
  483. +        for (int i = index + 1; i < totalFrames; i++) {
  484. +            if (keyFrames[i] != null) {
  485. +                return i;
  486. +            }
  487. +        }
  488. +        return -1;
  489. +    }
  490. +
  491. +    /**
  492. +     * Get the index of the previous keyFrame that as a transform
  493. +     * @param index the start index
  494. +     * @param keyFrames the keyFrames array
  495. +     * @return the index of the previous keyFrame
  496. +     */
  497. +    private int getPreviousKeyFrame(int index, Object[] keyFrames) {
  498. +        for (int i = index - 1; i >= 0; i--) {
  499. +            if (keyFrames[i] != null) {
  500. +                return i;
  501. +            }
  502. +        }
  503. +        return -1;
  504. +    }
  505. +}
  506. Index: core/com/jme3/animation/AnimationFactory.java
  507. --- core/com/jme3/animation/AnimationFactory.java Base (BASE)
  508. +++ core/com/jme3/animation/AnimationFactory.java Deletado Localmente
  509. @@ -1,496 +0,0 @@
  510. -/*
  511. - * Copyright (c) 2009-2012 jMonkeyEngine
  512. - * All rights reserved.
  513. - *
  514. - * Redistribution and use in source and binary forms, with or without
  515. - * modification, are permitted provided that the following conditions are
  516. - * met:
  517. - *
  518. - * * Redistributions of source code must retain the above copyright
  519. - *   notice, this list of conditions and the following disclaimer.
  520. - *
  521. - * * Redistributions in binary form must reproduce the above copyright
  522. - *   notice, this list of conditions and the following disclaimer in the
  523. - *   documentation and/or other materials provided with the distribution.
  524. - *
  525. - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  526. - *   may be used to endorse or promote products derived from this software
  527. - *   without specific prior written permission.
  528. - *
  529. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  530. - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  531. - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  532. - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  533. - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  534. - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  535. - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  536. - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  537. - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  538. - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  539. - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  540. - */
  541. -package com.jme3.animation;
  542. -
  543. -import com.jme3.math.FastMath;
  544. -import com.jme3.math.Quaternion;
  545. -import com.jme3.math.Transform;
  546. -import com.jme3.math.Vector3f;
  547. -
  548. -/**
  549. - * A convenience class to easily setup a spatial keyframed animation
  550. - * you can add some keyFrames for a given time or a given keyFrameIndex, for translation rotation and scale.
  551. - * The animationHelper will then generate an appropriate SpatialAnimation by interpolating values between the keyFrames.
  552. - * <br><br>
  553. - * Usage is : <br>
  554. - * - Create the AnimationHelper<br>
  555. - * - add some keyFrames<br>
  556. - * - call the buildAnimation() method that will retruna new Animation<br>
  557. - * - add the generated Animation to any existing AnimationControl<br>
  558. - * <br><br>
  559. - * Note that the first keyFrame (index 0) is defaulted with the identy transforms.
  560. - * If you want to change that you have to replace this keyFrame with any transform you want.
  561. - *
  562. - * @author Nehon
  563. - */
  564. -public class AnimationFactory {
  565. -
  566. -    /**
  567. -     * step for splitting rotation that have a n ange above PI/2
  568. -     */
  569. -    private final static float EULER_STEP = FastMath.QUARTER_PI * 3;
  570. -
  571. -    /**
  572. -     * enum to determine the type of interpolation
  573. -     */
  574. -    private enum Type {
  575. -
  576. -        Translation, Rotation, Scale;
  577. -    }
  578. -
  579. -    /**
  580. -     * Inner Rotation type class to kep track on a rotation Euler angle
  581. -     */
  582. -    protected class Rotation {
  583. -
  584. -        /**
  585. -         * The rotation Quaternion
  586. -         */
  587. -        Quaternion rotation = new Quaternion();
  588. -        /**
  589. -         * This rotation expressed in Euler angles
  590. -         */
  591. -        Vector3f eulerAngles = new Vector3f();
  592. -        /**
  593. -         * the index of the parent key frame is this keyFrame is a splitted rotation
  594. -         */
  595. -        int masterKeyFrame = -1;
  596. -
  597. -        public Rotation() {
  598. -            rotation.loadIdentity();
  599. -        }
  600. -
  601. -        void set(Quaternion rot) {
  602. -            rotation.set(rot);
  603. -            float[] a = new float[3];
  604. -            rotation.toAngles(a);
  605. -            eulerAngles.set(a[0], a[1], a[2]);
  606. -        }
  607. -
  608. -        void set(float x, float y, float z) {
  609. -            float[] a = {x, y, z};
  610. -            rotation.fromAngles(a);
  611. -            eulerAngles.set(x, y, z);
  612. -        }
  613. -    }
  614. -    /**
  615. -     * Name of the animation
  616. -     */
  617. -    protected String name;
  618. -    /**
  619. -     * frames per seconds
  620. -     */
  621. -    protected int fps;
  622. -    /**
  623. -     * Animation duration in seconds
  624. -     */
  625. -    protected float duration;
  626. -    /**
  627. -     * total number of frames
  628. -     */
  629. -    protected int totalFrames;
  630. -    /**
  631. -     * time per frame
  632. -     */
  633. -    protected float tpf;
  634. -    /**
  635. -     * Time array for this animation
  636. -     */
  637. -    protected float[] times;
  638. -    /**
  639. -     * Translation array for this animation
  640. -     */
  641. -    protected Vector3f[] translations;
  642. -    /**
  643. -     * rotation array for this animation
  644. -     */
  645. -    protected Quaternion[] rotations;
  646. -    /**
  647. -     * scales array for this animation
  648. -     */
  649. -    protected Vector3f[] scales;
  650. -    /**
  651. -     * The map of keyFrames to compute the animation. The key is the index of the frame
  652. -     */
  653. -    protected Vector3f[] keyFramesTranslation;
  654. -    protected Vector3f[] keyFramesScale;
  655. -    protected Rotation[] keyFramesRotation;
  656. -
  657. -    /**
  658. -     * Creates and AnimationHelper
  659. -     * @param duration the desired duration for the resulting animation
  660. -     * @param name the name of the resulting animation
  661. -     */
  662. -    public AnimationFactory(float duration, String name) {
  663. -        this(duration, name, 30);
  664. -    }
  665. -
  666. -    /**
  667. -     * Creates and AnimationHelper
  668. -     * @param duration the desired duration for the resulting animation
  669. -     * @param name the name of the resulting animation
  670. -     * @param fps the number of frames per second for this animation (default is 30)
  671. -     */
  672. -    public AnimationFactory(float duration, String name, int fps) {
  673. -        this.name = name;
  674. -        this.duration = duration;
  675. -        this.fps = fps;
  676. -        totalFrames = (int) (fps * duration) + 1;
  677. -        tpf = 1 / (float) fps;
  678. -        times = new float[totalFrames];
  679. -        translations = new Vector3f[totalFrames];
  680. -        rotations = new Quaternion[totalFrames];
  681. -        scales = new Vector3f[totalFrames];
  682. -        keyFramesTranslation = new Vector3f[totalFrames];
  683. -        keyFramesTranslation[0] = new Vector3f();
  684. -        keyFramesScale = new Vector3f[totalFrames];
  685. -        keyFramesScale[0] = new Vector3f(1, 1, 1);
  686. -        keyFramesRotation = new Rotation[totalFrames];
  687. -        keyFramesRotation[0] = new Rotation();
  688. -
  689. -    }
  690. -
  691. -    /**
  692. -     * Adds a key frame for the given Transform at the given time
  693. -     * @param time the time at which the keyFrame must be inserted
  694. -     * @param transform the transforms to use for this keyFrame
  695. -     */
  696. -    public void addTimeTransform(float time, Transform transform) {
  697. -        addKeyFrameTransform((int) (time / tpf), transform);
  698. -    }
  699. -
  700. -    /**
  701. -     * Adds a key frame for the given Transform at the given keyFrame index
  702. -     * @param keyFrameIndex the index at which the keyFrame must be inserted
  703. -     * @param transform the transforms to use for this keyFrame
  704. -     */
  705. -    public void addKeyFrameTransform(int keyFrameIndex, Transform transform) {
  706. -        addKeyFrameTranslation(keyFrameIndex, transform.getTranslation());
  707. -        addKeyFrameScale(keyFrameIndex, transform.getScale());
  708. -        addKeyFrameRotation(keyFrameIndex, transform.getRotation());
  709. -    }
  710. -
  711. -    /**
  712. -     * Adds a key frame for the given translation at the given time
  713. -     * @param time the time at which the keyFrame must be inserted
  714. -     * @param translation the translation to use for this keyFrame
  715. -     */
  716. -    public void addTimeTranslation(float time, Vector3f translation) {
  717. -        addKeyFrameTranslation((int) (time / tpf), translation);
  718. -    }
  719. -
  720. -    /**
  721. -     * Adds a key frame for the given translation at the given keyFrame index
  722. -     * @param keyFrameIndex the index at which the keyFrame must be inserted
  723. -     * @param translation the translation to use for this keyFrame
  724. -     */
  725. -    public void addKeyFrameTranslation(int keyFrameIndex, Vector3f translation) {
  726. -        Vector3f t = getTranslationForFrame(keyFrameIndex);
  727. -        t.set(translation);
  728. -    }
  729. -
  730. -    /**
  731. -     * Adds a key frame for the given rotation at the given time<br>
  732. -     * This can't be used if the interpolated angle is higher than PI (180°)<br>
  733. -     * Use {@link #addTimeRotationAngles(float time, float x, float y, float z)}  instead that uses Euler angles rotations.<br>     *
  734. -     * @param time the time at which the keyFrame must be inserted
  735. -     * @param rotation the rotation Quaternion to use for this keyFrame
  736. -     * @see #addTimeRotationAngles(float time, float x, float y, float z)
  737. -     */
  738. -    public void addTimeRotation(float time, Quaternion rotation) {
  739. -        addKeyFrameRotation((int) (time / tpf), rotation);
  740. -    }
  741. -
  742. -    /**
  743. -     * Adds a key frame for the given rotation at the given keyFrame index<br>
  744. -     * This can't be used if the interpolated angle is higher than PI (180°)<br>
  745. -     * Use {@link #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)} instead that uses Euler angles rotations.
  746. -     * @param keyFrameIndex the index at which the keyFrame must be inserted
  747. -     * @param rotation the rotation Quaternion to use for this keyFrame
  748. -     * @see #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)
  749. -     */
  750. -    public void addKeyFrameRotation(int keyFrameIndex, Quaternion rotation) {
  751. -        Rotation r = getRotationForFrame(keyFrameIndex);
  752. -        r.set(rotation);
  753. -    }
  754. -
  755. -    /**
  756. -     * Adds a key frame for the given rotation at the given time.<br>
  757. -     * Rotation is expressed by Euler angles values in radians.<br>
  758. -     * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
  759. -     * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
  760. -     *
  761. -     * @param time the time at which the keyFrame must be inserted
  762. -     * @param x the rotation around the x axis (aka yaw) in radians
  763. -     * @param y the rotation around the y axis (aka roll) in radians
  764. -     * @param z the rotation around the z axis (aka pitch) in radians
  765. -     */
  766. -    public void addTimeRotationAngles(float time, float x, float y, float z) {
  767. -        addKeyFrameRotationAngles((int) (time / tpf), x, y, z);
  768. -    }
  769. -
  770. -    /**
  771. -     * Adds a key frame for the given rotation at the given key frame index.<br>
  772. -     * Rotation is expressed by Euler angles values in radians.<br>
  773. -     * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
  774. -     * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
  775. -     *
  776. -     * @param keyFrameIndex the index at which the keyFrame must be inserted
  777. -     * @param x the rotation around the x axis (aka yaw) in radians
  778. -     * @param y the rotation around the y axis (aka roll) in radians
  779. -     * @param z the rotation around the z axis (aka pitch) in radians
  780. -     */
  781. -    public void addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z) {
  782. -        Rotation r = getRotationForFrame(keyFrameIndex);
  783. -        r.set(x, y, z);
  784. -
  785. -        // if the delta of euler angles is higher than PI, we create intermediate keyframes
  786. -        // since we are using quaternions and slerp for rotation interpolation, we cannot interpolate over an angle higher than PI
  787. -        int prev = getPreviousKeyFrame(keyFrameIndex, keyFramesRotation);
  788. -        if (prev != -1) {
  789. -            //previous rotation keyframe
  790. -            Rotation prevRot = keyFramesRotation[prev];
  791. -            //the maximum delta angle (x,y or z)
  792. -            float delta = Math.max(Math.abs(x - prevRot.eulerAngles.x), Math.abs(y - prevRot.eulerAngles.y));
  793. -            delta = Math.max(delta, Math.abs(z - prevRot.eulerAngles.z));
  794. -            //if delta > PI we have to create intermediates key frames
  795. -            if (delta >= FastMath.PI) {
  796. -                //frames delta
  797. -                int dF = keyFrameIndex - prev;
  798. -                //angle per frame for x,y ,z
  799. -                float dXAngle = (x - prevRot.eulerAngles.x) / (float) dF;
  800. -                float dYAngle = (y - prevRot.eulerAngles.y) / (float) dF;
  801. -                float dZAngle = (z - prevRot.eulerAngles.z) / (float) dF;
  802. -
  803. -                // the keyFrame step
  804. -                int keyStep = (int) (((float) (dF)) / delta * (float) EULER_STEP);
  805. -                // the current keyFrame
  806. -                int cursor = prev + keyStep;
  807. -                while (cursor < keyFrameIndex) {
  808. -                    //for each step we create a new rotation by interpolating the angles
  809. -                    Rotation dr = getRotationForFrame(cursor);
  810. -                    dr.masterKeyFrame = keyFrameIndex;
  811. -                    dr.set(prevRot.eulerAngles.x + cursor * dXAngle, prevRot.eulerAngles.y + cursor * dYAngle, prevRot.eulerAngles.z + cursor * dZAngle);
  812. -                    cursor += keyStep;
  813. -                }
  814. -
  815. -            }
  816. -        }
  817. -
  818. -    }
  819. -
  820. -    /**
  821. -     * Adds a key frame for the given scale at the given time
  822. -     * @param time the time at which the keyFrame must be inserted
  823. -     * @param scale the scale to use for this keyFrame
  824. -     */
  825. -    public void addTimeScale(float time, Vector3f scale) {
  826. -        addKeyFrameScale((int) (time / tpf), scale);
  827. -    }
  828. -
  829. -    /**
  830. -     * Adds a key frame for the given scale at the given keyFrame index
  831. -     * @param keyFrameIndex the index at which the keyFrame must be inserted
  832. -     * @param scale the scale to use for this keyFrame
  833. -     */
  834. -    public void addKeyFrameScale(int keyFrameIndex, Vector3f scale) {
  835. -        Vector3f s = getScaleForFrame(keyFrameIndex);
  836. -        s.set(scale);
  837. -    }
  838. -
  839. -    /**
  840. -     * returns the translation for a given frame index
  841. -     * creates the translation if it doesn't exists
  842. -     * @param keyFrameIndex index
  843. -     * @return the translation
  844. -     */
  845. -    private Vector3f getTranslationForFrame(int keyFrameIndex) {
  846. -        if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
  847. -            throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
  848. -        }
  849. -        Vector3f v = keyFramesTranslation[keyFrameIndex];
  850. -        if (v == null) {
  851. -            v = new Vector3f();
  852. -            keyFramesTranslation[keyFrameIndex] = v;
  853. -        }
  854. -        return v;
  855. -    }
  856. -
  857. -    /**
  858. -     * returns the scale for a given frame index
  859. -     * creates the scale if it doesn't exists
  860. -     * @param keyFrameIndex index
  861. -     * @return the scale
  862. -     */
  863. -    private Vector3f getScaleForFrame(int keyFrameIndex) {
  864. -        if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
  865. -            throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
  866. -        }
  867. -        Vector3f v = keyFramesScale[keyFrameIndex];
  868. -        if (v == null) {
  869. -            v = new Vector3f();
  870. -            keyFramesScale[keyFrameIndex] = v;
  871. -        }
  872. -        return v;
  873. -    }
  874. -
  875. -    /**
  876. -     * returns the rotation for a given frame index
  877. -     * creates the rotation if it doesn't exists
  878. -     * @param keyFrameIndex index
  879. -     * @return the rotation
  880. -     */
  881. -    private Rotation getRotationForFrame(int keyFrameIndex) {
  882. -        if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
  883. -            throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
  884. -        }
  885. -        Rotation v = keyFramesRotation[keyFrameIndex];
  886. -        if (v == null) {
  887. -            v = new Rotation();
  888. -            keyFramesRotation[keyFrameIndex] = v;
  889. -        }
  890. -        return v;
  891. -    }
  892. -
  893. -    /**
  894. -     * Creates an Animation based on the keyFrames previously added to the helper.
  895. -     * @return the generated animation
  896. -     */
  897. -    public Animation buildAnimation() {
  898. -        interpolateTime();
  899. -        interpolate(keyFramesTranslation, Type.Translation);
  900. -        interpolate(keyFramesRotation, Type.Rotation);
  901. -        interpolate(keyFramesScale, Type.Scale);
  902. -
  903. -        SpatialTrack spatialTrack = new SpatialTrack(times, translations, rotations, scales);
  904. -
  905. -        //creating the animation
  906. -        Animation spatialAnimation = new Animation(name, duration);
  907. -        spatialAnimation.setTracks(new SpatialTrack[]{spatialTrack});
  908. -
  909. -        return spatialAnimation;
  910. -    }
  911. -
  912. -    /**
  913. -     * interpolates time values
  914. -     */
  915. -    private void interpolateTime() {
  916. -        for (int i = 0; i < totalFrames; i++) {
  917. -            times[i] = i * tpf;
  918. -        }
  919. -    }
  920. -
  921. -    /**
  922. -     * Interpolates over the key frames for the given keyFrame array and the given type of transform
  923. -     * @param keyFrames the keyFrames array
  924. -     * @param type the type of transforms
  925. -     */
  926. -    private void interpolate(Object[] keyFrames, Type type) {
  927. -        int i = 0;
  928. -        while (i < totalFrames) {
  929. -            //fetching the next keyFrame index transform in the array
  930. -            int key = getNextKeyFrame(i, keyFrames);
  931. -            if (key != -1) {
  932. -                //computing the frame span to interpolate over
  933. -                int span = key - i;
  934. -                //interating over the frames
  935. -                for (int j = i; j <= key; j++) {
  936. -                    // computing interpolation value
  937. -                    float val = (float) (j - i) / (float) span;
  938. -                    //interpolationg depending on the transform type
  939. -                    switch (type) {
  940. -                        case Translation:
  941. -                            translations[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
  942. -                            break;
  943. -                        case Rotation:
  944. -                            Quaternion rot = new Quaternion();
  945. -                            rotations[j] = rot.slerp(((Rotation) keyFrames[i]).rotation, ((Rotation) keyFrames[key]).rotation, val);
  946. -                            break;
  947. -                        case Scale:
  948. -                            scales[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
  949. -                            break;
  950. -                    }
  951. -                }
  952. -                //jumping to the next keyFrame
  953. -                i = key;
  954. -            } else {
  955. -                //No more key frame, filling the array witht he last transform computed.
  956. -                for (int j = i; j < totalFrames; j++) {
  957. -
  958. -                    switch (type) {
  959. -                        case Translation:
  960. -                            translations[j] = ((Vector3f) keyFrames[i]).clone();
  961. -                            break;
  962. -                        case Rotation:
  963. -                            rotations[j] = ((Quaternion) ((Rotation) keyFrames[i]).rotation).clone();
  964. -                            break;
  965. -                        case Scale:
  966. -                            scales[j] = ((Vector3f) keyFrames[i]).clone();
  967. -                            break;
  968. -                    }
  969. -                }
  970. -                //we're done
  971. -                i = totalFrames;
  972. -            }
  973. -        }
  974. -    }
  975. -
  976. -    /**
  977. -     * Get the index of the next keyFrame that as a transform
  978. -     * @param index the start index
  979. -     * @param keyFrames the keyFrames array
  980. -     * @return the index of the next keyFrame
  981. -     */
  982. -    private int getNextKeyFrame(int index, Object[] keyFrames) {
  983. -        for (int i = index + 1; i < totalFrames; i++) {
  984. -            if (keyFrames[i] != null) {
  985. -                return i;
  986. -            }
  987. -        }
  988. -        return -1;
  989. -    }
  990. -
  991. -    /**
  992. -     * Get the index of the previous keyFrame that as a transform
  993. -     * @param index the start index
  994. -     * @param keyFrames the keyFrames array
  995. -     * @return the index of the previous keyFrame
  996. -     */
  997. -    private int getPreviousKeyFrame(int index, Object[] keyFrames) {
  998. -        for (int i = index - 1; i >= 0; i--) {
  999. -            if (keyFrames[i] != null) {
  1000. -                return i;
  1001. -            }
  1002. -        }
  1003. -        return -1;
  1004. -    }
  1005. -}
  1006. Index: test/jme3test/animation/TestCinematic.java
  1007. --- test/jme3test/animation/TestCinematic.java Base (BASE)
  1008. +++ test/jme3test/animation/TestCinematic.java Modificado Localmente (Baseado em LOCAL)
  1009. @@ -32,7 +32,7 @@
  1010.  package jme3test.animation;
  1011.  
  1012.  import com.jme3.animation.AnimControl;
  1013. -import com.jme3.animation.AnimationFactory;
  1014. +import com.jme3.animation.AnimationBuilder;
  1015.  import com.jme3.animation.LoopMode;
  1016.  import com.jme3.app.SimpleApplication;
  1017.  import com.jme3.cinematic.Cinematic;
  1018. @@ -107,14 +107,14 @@
  1019.          createCameraMotion();
  1020.  
  1021.          //creating spatial animation for the teapot
  1022. -        AnimationFactory factory = new AnimationFactory(20, "teapotAnim");
  1023. -        factory.addTimeTranslation(0, new Vector3f(10, 0, 10));
  1024. -        factory.addTimeTranslation(20, new Vector3f(10, 0, -10));
  1025. -        factory.addTimeScale(10, new Vector3f(4, 4, 4));
  1026. -        factory.addTimeScale(20, new Vector3f(1, 1, 1));
  1027. -        factory.addTimeRotationAngles(20, 0, 4 * FastMath.TWO_PI, 0);
  1028. +        AnimationBuilder builder = new AnimationBuilder(20, "teapotAnim");
  1029. +        builder.addTimeTranslation(0, new Vector3f(10, 0, 10));
  1030. +        builder.addTimeTranslation(20, new Vector3f(10, 0, -10));
  1031. +        builder.addTimeScale(10, new Vector3f(4, 4, 4));
  1032. +        builder.addTimeScale(20, new Vector3f(1, 1, 1));
  1033. +        builder.addTimeRotationAngles(20, 0, 4 * FastMath.TWO_PI, 0);
  1034.          AnimControl control = new AnimControl();
  1035. -        control.addAnim(factory.buildAnimation());
  1036. +        control.addAnim(builder.build());
  1037.          teapot.addControl(control);
  1038.  
  1039.          //fade in
  1040. Index: test/jme3test/animation/TestJaime.java
  1041. --- test/jme3test/animation/TestJaime.java Base (BASE)
  1042. +++ test/jme3test/animation/TestJaime.java Modificado Localmente (Baseado em LOCAL)
  1043. @@ -32,7 +32,7 @@
  1044.  package jme3test.animation;
  1045.  
  1046.  import com.jme3.animation.AnimControl;
  1047. -import com.jme3.animation.AnimationFactory;
  1048. +import com.jme3.animation.AnimationBuilder;
  1049.  import com.jme3.animation.LoopMode;
  1050.  import com.jme3.app.DebugKeysAppState;
  1051.  import com.jme3.app.FlyCamAppState;
  1052. @@ -149,11 +149,11 @@
  1053.          stateManager.attach(cinematic);
  1054.          
  1055.          jaime.move(0, 0, -3);
  1056. -        AnimationFactory af = new AnimationFactory(0.7f, "JumpForward");
  1057. -        af.addTimeTranslation(0, new Vector3f(0, 0, -3));
  1058. -        af.addTimeTranslation(0.35f, new Vector3f(0, 1, -1.5f));
  1059. -        af.addTimeTranslation(0.7f, new Vector3f(0, 0, 0));
  1060. -        jaime.getControl(AnimControl.class).addAnim(af.buildAnimation());
  1061. +        AnimationBuilder ab = new AnimationBuilder(0.7f, "JumpForward");
  1062. +        ab.addTimeTranslation(0, new Vector3f(0, 0, -3));
  1063. +        ab.addTimeTranslation(0.35f, new Vector3f(0, 1, -1.5f));
  1064. +        ab.addTimeTranslation(0.7f, new Vector3f(0, 0, 0));
  1065. +        jaime.getControl(AnimControl.class).addAnim(ab.build());
  1066.    
  1067.          cinematic.enqueueCinematicEvent(new AnimationEvent(jaime, "Idle",3, LoopMode.DontLoop));
  1068.          float jumpStart = cinematic.enqueueCinematicEvent(new AnimationEvent(jaime, "JumpStart", LoopMode.DontLoop));
  1069. Index: test/jme3test/model/anim/TestAnimationBuilder.java
  1070. --- test/jme3test/model/anim/TestAnimationBuilder.java Nenhuma Revisão de Base
  1071. +++ test/jme3test/model/anim/TestAnimationBuilder.java Novo Localmente
  1072. @@ -0,0 +1,85 @@
  1073. +package jme3test.model.anim;
  1074. +
  1075. +import com.jme3.animation.AnimControl;
  1076. +import com.jme3.animation.AnimationBuilder;
  1077. +import com.jme3.app.SimpleApplication;
  1078. +import com.jme3.light.AmbientLight;
  1079. +import com.jme3.light.DirectionalLight;
  1080. +import com.jme3.math.FastMath;
  1081. +import com.jme3.math.Quaternion;
  1082. +import com.jme3.math.Vector3f;
  1083. +import com.jme3.scene.Geometry;
  1084. +import com.jme3.scene.Node;
  1085. +import com.jme3.scene.shape.Box;
  1086. +import com.jme3.util.TangentBinormalGenerator;
  1087. +
  1088. +public class TestAnimationBuilder extends SimpleApplication {
  1089. +
  1090. +    public static void main(String[] args) {
  1091. +        TestAnimationBuilder app = new TestAnimationBuilder();
  1092. +        app.start();
  1093. +    }
  1094. +
  1095. +    @Override
  1096. +    public void simpleInitApp() {
  1097. +
  1098. +        AmbientLight al = new AmbientLight();
  1099. +        rootNode.addLight(al);
  1100. +
  1101. +        DirectionalLight dl = new DirectionalLight();
  1102. +        dl.setDirection(Vector3f.UNIT_XYZ.negate());
  1103. +        rootNode.addLight(dl);
  1104. +
  1105. +        // Create model
  1106. +        Box box = new Box(1, 1, 1);
  1107. +        Geometry geom = new Geometry("box", box);
  1108. +        geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
  1109. +        Node model = new Node("model");
  1110. +        model.attachChild(geom);
  1111. +
  1112. +        Box child = new Box(0.5f, 0.5f, 0.5f);
  1113. +        Geometry childGeom = new Geometry("box", child);
  1114. +        childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
  1115. +        Node childModel = new Node("childmodel");
  1116. +        childModel.setLocalTranslation(2, 2, 2);
  1117. +        childModel.attachChild(childGeom);
  1118. +        model.attachChild(childModel);
  1119. +        TangentBinormalGenerator.generate(model);
  1120. +
  1121. +        //creating quite complex animation witht the AnimationBuilder
  1122. +        // animation of 6 seconds named "anim" and with 25 frames per second
  1123. +        AnimationBuilder animationBuilder = new AnimationBuilder(6, "anim", 25);
  1124. +        
  1125. +        //creating a translation keyFrame at time = 3 with a translation on the x axis of 5 WU        
  1126. +        animationBuilder.addTimeTranslation(3, new Vector3f(5, 0, 0));
  1127. +        //reseting the translation to the start position at time = 6
  1128. +        animationBuilder.addTimeTranslation(6, new Vector3f(0, 0, 0));
  1129. +
  1130. +        //Creating a scale keyFrame at time = 2 with the unit scale.
  1131. +        animationBuilder.addTimeScale(2, new Vector3f(1, 1, 1));
  1132. +        //Creating a scale keyFrame at time = 4 scaling to 1.5
  1133. +        animationBuilder.addTimeScale(4, new Vector3f(1.5f, 1.5f, 1.5f));
  1134. +        //reseting the scale to the start value at time = 5
  1135. +        animationBuilder.addTimeScale(5, new Vector3f(1, 1, 1));
  1136. +
  1137. +        
  1138. +        //Creating a rotation keyFrame at time = 0.5 of quarter PI around the Z axis
  1139. +        animationBuilder.addTimeRotation(0.5f,new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Z));
  1140. +        //rotating back to initial rotation value at time = 1
  1141. +        animationBuilder.addTimeRotation(1,Quaternion.IDENTITY);
  1142. +        //Creating a rotation keyFrame at time = 2. Note that i used the Euler angle version because the angle is higher than PI
  1143. +        //this should result in a complete revolution of the spatial around the x axis in 1 second (from 1 to 2)
  1144. +        animationBuilder.addTimeRotationAngles(2, FastMath.TWO_PI,0, 0);
  1145. +
  1146. +
  1147. +        AnimControl control = new AnimControl();
  1148. +        control.addAnim(animationBuilder.build());
  1149. +
  1150. +        model.addControl(control);
  1151. +
  1152. +        rootNode.attachChild(model);
  1153. +
  1154. +        //run animation
  1155. +        control.createChannel().setAnim("anim");
  1156. +    }
  1157. +}
  1158. Index: test/jme3test/model/anim/TestAnimationFactory.java
  1159. --- test/jme3test/model/anim/TestAnimationFactory.java Base (BASE)
  1160. +++ test/jme3test/model/anim/TestAnimationFactory.java Deletado Localmente
  1161. @@ -1,85 +0,0 @@
  1162. -package jme3test.model.anim;
  1163. -
  1164. -import com.jme3.animation.AnimControl;
  1165. -import com.jme3.animation.AnimationFactory;
  1166. -import com.jme3.app.SimpleApplication;
  1167. -import com.jme3.light.AmbientLight;
  1168. -import com.jme3.light.DirectionalLight;
  1169. -import com.jme3.math.FastMath;
  1170. -import com.jme3.math.Quaternion;
  1171. -import com.jme3.math.Vector3f;
  1172. -import com.jme3.scene.Geometry;
  1173. -import com.jme3.scene.Node;
  1174. -import com.jme3.scene.shape.Box;
  1175. -import com.jme3.util.TangentBinormalGenerator;
  1176. -
  1177. -public class TestAnimationFactory extends SimpleApplication {
  1178. -
  1179. -    public static void main(String[] args) {
  1180. -        TestSpatialAnim app = new TestSpatialAnim();
  1181. -        app.start();
  1182. -    }
  1183. -
  1184. -    @Override
  1185. -    public void simpleInitApp() {
  1186. -
  1187. -        AmbientLight al = new AmbientLight();
  1188. -        rootNode.addLight(al);
  1189. -
  1190. -        DirectionalLight dl = new DirectionalLight();
  1191. -        dl.setDirection(Vector3f.UNIT_XYZ.negate());
  1192. -        rootNode.addLight(dl);
  1193. -
  1194. -        // Create model
  1195. -        Box box = new Box(1, 1, 1);
  1196. -        Geometry geom = new Geometry("box", box);
  1197. -        geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
  1198. -        Node model = new Node("model");
  1199. -        model.attachChild(geom);
  1200. -
  1201. -        Box child = new Box(0.5f, 0.5f, 0.5f);
  1202. -        Geometry childGeom = new Geometry("box", child);
  1203. -        childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
  1204. -        Node childModel = new Node("childmodel");
  1205. -        childModel.setLocalTranslation(2, 2, 2);
  1206. -        childModel.attachChild(childGeom);
  1207. -        model.attachChild(childModel);
  1208. -        TangentBinormalGenerator.generate(model);
  1209. -
  1210. -        //creating quite complex animation witht the AnimationHelper
  1211. -        // animation of 6 seconds named "anim" and with 25 frames per second
  1212. -        AnimationFactory animationFactory = new AnimationFactory(6, "anim", 25);
  1213. -        
  1214. -        //creating a translation keyFrame at time = 3 with a translation on the x axis of 5 WU        
  1215. -        animationFactory.addTimeTranslation(3, new Vector3f(5, 0, 0));
  1216. -        //reseting the translation to the start position at time = 6
  1217. -        animationFactory.addTimeTranslation(6, new Vector3f(0, 0, 0));
  1218. -
  1219. -        //Creating a scale keyFrame at time = 2 with the unit scale.
  1220. -        animationFactory.addTimeScale(2, new Vector3f(1, 1, 1));
  1221. -        //Creating a scale keyFrame at time = 4 scaling to 1.5
  1222. -        animationFactory.addTimeScale(4, new Vector3f(1.5f, 1.5f, 1.5f));
  1223. -        //reseting the scale to the start value at time = 5
  1224. -        animationFactory.addTimeScale(5, new Vector3f(1, 1, 1));
  1225. -
  1226. -        
  1227. -        //Creating a rotation keyFrame at time = 0.5 of quarter PI around the Z axis
  1228. -        animationFactory.addTimeRotation(0.5f,new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Z));
  1229. -        //rotating back to initial rotation value at time = 1
  1230. -        animationFactory.addTimeRotation(1,Quaternion.IDENTITY);
  1231. -        //Creating a rotation keyFrame at time = 2. Note that i used the Euler angle version because the angle is higher than PI
  1232. -        //this should result in a complete revolution of the spatial around the x axis in 1 second (from 1 to 2)
  1233. -        animationFactory.addTimeRotationAngles(2, FastMath.TWO_PI,0, 0);
  1234. -
  1235. -
  1236. -        AnimControl control = new AnimControl();
  1237. -        control.addAnim(animationFactory.buildAnimation());
  1238. -
  1239. -        model.addControl(control);
  1240. -
  1241. -        rootNode.attachChild(model);
  1242. -
  1243. -        //run animation
  1244. -        control.createChannel().setAnim("anim");
  1245. -    }
  1246. -}
Advertisement
Add Comment
Please, Sign In to add comment