JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
AnimGroup.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-2023 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.graph.ui;
29
30import java.util.ArrayList;
31import java.util.List;
32import java.util.Random;
33
34import com.jogamp.common.os.Clock;
35import com.jogamp.graph.curve.opengl.GLRegion;
36import com.jogamp.graph.curve.opengl.RegionRenderer;
37import com.jogamp.graph.font.Font;
38import com.jogamp.graph.font.Font.Glyph;
39import com.jogamp.graph.ui.Group.Layout;
40import com.jogamp.graph.ui.shapes.GlyphShape;
41import com.jogamp.math.FloatUtil;
42import com.jogamp.math.Quaternion;
43import com.jogamp.math.Recti;
44import com.jogamp.math.Vec2f;
45import com.jogamp.math.Vec3f;
46import com.jogamp.math.Vec4f;
47import com.jogamp.math.geom.AABBox;
48import com.jogamp.math.geom.plane.AffineTransform;
49import com.jogamp.math.util.PMVMatrix4f;
50import com.jogamp.opengl.GL2ES2;
51import com.jogamp.opengl.GLProfile;
52import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
53
54/**
55 * Group of animated {@link Shape}s including other static {@link Shape}s, optionally utilizing a {@link Group.Layout}.
56 * @see Scene
57 * @see Shape
58 * @see Group.Layout
59 */
60public class AnimGroup extends Group {
61 private static final boolean DEBUG = false;
62 /** Epsilon of position, 5000 x {@link FloatUtil#EPSILON} */
63 public static final float POS_EPS = FloatUtil.EPSILON * 5000; // ~= 0.0005960
64 /** Epsilon of rotation [radian], 0.5 degrees or 0.008726646 radians */
65 public static final float ROT_EPS = FloatUtil.adegToRad(0.5f); // 1 adeg ~= 0.01745 rad
66
67 private volatile long tstart_us = 0;
68 private volatile long tlast_us = 0;
69 private volatile long tpause_us = 0;
70 private volatile boolean tickOnDraw = true;
71 private volatile boolean tickPaused = false;
72 private long frame_count = 0;
73
74 /** Animation {@link Shapes} data covering one {@link Shape} of {@link Set}. */
75 public static final class ShapeData {
76 /** Indicator whether the {@link Shapes} is animating or not. */
77 public boolean active;
78 /** {@link Shapes} scaled start position */
79 public final Vec3f startPos;
80 /** {@link Shapes} scaled target position */
81 public final Vec3f targetPos;
82 /** The {@link Shapes} */
83 public final Shape shape;
84 /** Optional user attachment per {@link Shape} to be used within {@link LerpFunc}. */
85 public Object user;
86
87 /** New instance with set {@link Shape} using its scaled {@link Shape#getPosition()} for {@link #startPos} and {@link #targetPos}. */
88 public ShapeData(final Shape s) {
89 active = true;
90 startPos = new Vec3f( s.getPosition() );
92 shape = s;
93 user = null;
94 }
95 }
96
97 /** Animation-Set covering its {@link ShapeData} elements, {@link LerpFunc} and animation parameter. */
98 public static final class Set {
99 /** Pixel per millimeter */
100 public final float pixPerMM;
101 /** Pixel per shape unit */
102 public final Vec2f pixPerShapeUnit;
103 /** Reference {@link Shape} giving reference size */
104 public final Shape refShape;
105
106 /** Translation acceleration in [m]/[s*s] */
107 public final float accel;
108 /** Translation acceleration in [shapeUnit]/[s*s] */
109 public final float accel_obj;
110 /** Start translation velocity in [m]/[s] */
111 public final float start_velocity;
112 /** Start translation velocity in [shapeUnit]/[s] */
113 public final float start_velocity_obj;
114 /** Current translation velocity in [m]/[s] */
115 public float velocity;
116 /** Current translation velocity in [shapeUnit]/[s] */
117 public float velocity_obj;
118
119 /** Angular acceleration in [radians]/[s*s] */
120 public final float ang_accel;
121 /** Start angular velocity in [radians]/[s] */
122 public final float start_ang_velo;
123 /** Current angular velocity in [radians]/[s] */
124 public float ang_velo;
125
126 /** {@link LerpFunc} function */
127 public final LerpFunc lerp;
128
129 /** All {@link Shape}s wrapped within {@link ShapeData}. */
130 public final List<ShapeData> allShapes;
131
132 /** Unscaled bounds of {@link #allShapes} at their original position, size and rotation. */
133 public final AABBox sourceBounds;
134
135 private Set(final float pixPerMM, final float[/*2*/] pixPerShapeUnit, final Shape refShape,
136 final float accel, final float velocity,
137 final float ang_accel, final float ang_velo,
138 final List<ShapeData> allShapes, final AABBox sourceBounds,
139 final LerpFunc lerp) {
140 this.pixPerMM = pixPerMM;
141 this.pixPerShapeUnit = new Vec2f( pixPerShapeUnit );
142 this.refShape = refShape;
143 this.accel = accel;
144 this.start_velocity = velocity;
145 this.velocity = velocity;
146 {
147 final float accel_px = accel * 1e3f * pixPerMM; // [px]/[s*s]
148 this.accel_obj = accel_px / this.pixPerShapeUnit.x(); // [shapeUnit]/[s*s]
149
150 final float velocity_px = velocity * 1e3f * pixPerMM; // [px]/[s]
151 this.start_velocity_obj = velocity_px / this.pixPerShapeUnit.x(); // [shapeUnit]/[s]
152 this.velocity_obj = this.start_velocity_obj;
153 }
154 this.ang_accel = ang_accel;
155 this.start_ang_velo = ang_velo;
156 this.ang_velo = ang_velo;
157 this.lerp = lerp;
158 this.allShapes = allShapes;
159 this.sourceBounds = sourceBounds;
160 }
161
162 /**
163 * Adds given {@link Shape} to this {@link Set} and its {@link AnimGroup} wrapping it in {@link ShapeData}.
164 * <p>
165 * Also issues {@link ShapeSetup#setup(Set, int, ShapeData)}.
166 * </p>
167 * @return newly created {@link ShapeData}
168 */
169 public ShapeData addShape(final AnimGroup g, final Shape s, final ShapeSetup op) {
170 final ShapeData sd = new ShapeData(s);
171 final int idx = this.allShapes.size();
172 this.allShapes.add( sd );
173 this.sourceBounds.resize(sd.shape.getBounds());
174 op.setup(this, idx, sd);
175 g.addShape(sd.shape);
176 return sd;
177 }
178
179 /**
180 * Removes given {@link ShapeData} from this {@link Set} and its {@link AnimGroup}.
181 * <p>
182 * Also destroys the {@link ShapeData}, including its {@link ShapeData} and their {@link Shape}.
183 * </p>
184 */
185 public void removeShape(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer, final ShapeData sd) {
186 g.removeShape(gl, renderer, sd.shape);
187 sd.active = false;
188 allShapes.remove(sd);
189 }
190
191 /**
192 * Removes all {@link ShapeData} from this {@link Set} and its {@link AnimGroup}.
193 * <p>
194 * Also destroys the {@link ShapeData}, including its {@link ShapeData} and their {@link Shape}.
195 * </p>
196 */
197 public void removeShapes(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer) {
198 for(final ShapeData sd : allShapes) {
199 g.removeShape(gl, renderer, sd.shape);
200 sd.active = false;
201 }
202 allShapes.clear();
203 }
204
205 /** Removes this {@link Set} from its {@link AnimGroup} and destroys it, including its {@link ShapeData} and their {@link Shape}. */
206 private void remove(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer) {
207 removeShapes(g, gl, renderer);
208 refShape.destroy(gl, renderer);
209 }
210
211 public void setAnimationActive(final boolean v) {
212 for(final ShapeData sd : allShapes) {
213 sd.active = v;
214 }
215 }
216 public boolean isAnimationActive() {
217 for(final ShapeData sd : allShapes) {
218 if( sd.active ) { return true; }
219 }
220 return false;
221 }
222 }
223 private final List<Set> animSets = new ArrayList<Set>();
224
225 /**
226 * Create a group of animated {@link Shape}s including other static {@link Shape}s w/ given {@link Group.Layout}.
227 * <p>
228 * Default is non-interactive, see {@link #setInteractive(boolean)}.
229 * </p>
230 * @param l optional {@link Layout}, maybe {@code null}
231 */
232 public AnimGroup(final Layout l) {
233 super(l);
234 }
235
236 /** Return the {@link Set} at given index or {@code null} if n/a. */
237 public Set getAnimSet(final int idx) {
238 if( idx < animSets.size() ) {
239 return animSets.get(idx);
240 }
241 return null;
242 }
243
244 /** Removes all {@link Set}s and destroys them, including all {@link ShapeData} and their {@link Shape}s. */
245 public final void removeAllAnimSets(final GL2ES2 gl, final RegionRenderer renderer) {
246 for(final Set as : animSets) {
247 as.remove(this, gl, renderer);
248 }
249 animSets.clear();
250 }
251
252 /** Removes the given {@link Set} and destroys it, including its {@link ShapeData} and {@link Shape}. */
253 public final void removeAnimSet(final GL2ES2 gl, final RegionRenderer renderer, final Set as) {
254 if( null != as ) {
255 as.remove(this, gl, renderer);
256 animSets.remove(as);
257 }
258 }
259
260 /** Removes the given {@link Set}s and destroys them, including their {@link ShapeData} and {@link Shape}. */
261 public final void removeAnimSets(final GL2ES2 gl, final RegionRenderer renderer, final List<Set> asList) {
262 for(final Set as : asList) {
263 if( null != as ) {
264 as.remove(this, gl, renderer);
265 animSets.remove(as);
266 }
267 }
268 }
269
270 /**
271 * {@link ShapeData} setup function for animation using its enclosing {@link Set} and other data points
272 * <p>
273 * At minimum, {@link ShapeData}'s {@link ShapeData#startPos} and {@link ShapeData#targetPos} shall be adjusted.
274 * </p>
275 */
276 public static interface ShapeSetup {
277 /**
278 * Setting up the {@link ShapeData} for animation using its enclosing {@link Set} and other data points
279 * @param as {@link Set} of the animation
280 * @param idx {@link ShapeData} index within the {@link Set#allShapes}
281 * @param sd the {@link ShapeData} matching {@code idx} containing the {@link Shape} to apply this operation
282 */
283 public void setup(final Set as, final int idx, final ShapeData sd);
284 }
285
286 /**
287 * Linear interpolation (LERP) function to evaluate the next animated frame for each {@link ShapeData} of a {@link Set}.
288 * @see AnimGroup.TargetLerp
289 */
290 public static interface LerpFunc {
291 /**
292 * Evaluate next LERP step for the given {@link ShapeData} within the animation {@link Set}.
293 * @param frame_cnt frame count for the given {@link ShapeData}
294 * @param as {@link Set} of the animation
295 * @param idx {@link ShapeData} index within the {@link Set#allShapes}
296 * @param sd the {@link ShapeData} matching {@code idx} containing the {@link Shape} to apply this operation
297 * @param at_s time delta to animation start, i.e. animation duration [s]
298 * @param dt_s time delta to last call [s]
299 * @return true if target animation shall continue, false otherwise
300 */
301 public boolean eval(long frame_cnt, Set as, final int idx, ShapeData sd, float at_s, float dt_s);
302 }
303
304 /**
305 * Add a new {@link Set} with an empty {@link ShapeData} container.
306 * <p>
307 * The given {@link PMVMatrix4f} has to be setup properly for this object,
308 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
309 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
310 * </p>
311 * @param pixPerMM monitor pixel per millimeter for accurate animation
312 * @param glp used {@link GLProfile}
313 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
314 * @param viewport the int[4] viewport
315 * @param accel translation acceleration in [m]/[s*s]
316 * @param velocity translation velocity in [m]/[s]
317 * @param ang_accel angular acceleration in [radians]/[s*s], usable for rotation etc
318 * @param ang_velo angular velocity in [radians]/[s], usable for rotation etc
319 * @param lerp {@link LerpFunc} function, see {@link AnimGroup.TargetLerp}
320 * @param refShape reference {@link Shape} giving reference size, see {@link #refShape}
321 * @param op {@link ShapeData} setup function for {@link ShapeData#startPos} and {@link ShapeData#targetPos}
322 * @return a new {@link Set} instance
323 */
324 public Set addAnimSet(final float pixPerMM,
325 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport,
326 final float accel, final float velocity,
327 final float ang_accel, final float ang_velo,
328 final LerpFunc lerp, final Shape refShape)
329 {
330 final Set as;
331 refShape.validate(glp);
332 pmv.pushMv();
333 {
334 refShape.applyMatToMv(pmv);
335 as = new Set(pixPerMM, refShape.getPixelPerShapeUnit(pmv, viewport, new float[2]), refShape,
336 accel, velocity, ang_accel, ang_velo,
337 new ArrayList<ShapeData>(), new AABBox(), lerp);
338 }
339 pmv.popMv();
340 animSets.add(as);
341 return as;
342 }
343
344 /**
345 * Add a new {@link Set} with {@link ShapeData} for each {@link GlyphShape}, moving towards its target position
346 * using a generic displacement via {@link ShapeSetup} to determine each {@link ShapeData}'s starting position.
347 * <p>
348 * The given {@link PMVMatrix4f} has to be setup properly for this object,
349 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
350 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
351 * </p>
352 * @param pixPerMM monitor pixel per millimeter for accurate animation
353 * @param glp used {@link GLProfile}
354 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
355 * @param viewport the int[4] viewport
356 * @param renderModes used {@link GLRegion#create(GLProfile, int, com.jogamp.opengl.util.texture.TextureSequence) region render-modes}
357 * @param font {@link Font} to be used for resulting {@link GlyphShape}s
358 * @param refChar reference character to calculate the reference {@link GlyphShape}
359 * @param text the text for resulting {@link GlyphShape}s
360 * @param fontScale font scale factor for resulting {@link GlyphShape}s
361 * @param accel translation acceleration in [m]/[s*s]
362 * @param velocity translation velocity in [m]/[s]
363 * @param ang_accel angular acceleration in [radians]/[s*s], usable for rotation etc
364 * @param ang_velo angular velocity in [radians]/[s], usable for rotation etc
365 * @param lerp {@link LerpFunc} function, see {@link AnimGroup.TargetLerp}
366 * @param op {@link ShapeData} setup function for {@link ShapeData#startPos} and {@link ShapeData#targetPos}
367 * @return newly created and added {@link Set}
368 */
369 public final Set addGlyphSet(final float pixPerMM,
370 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes,
371 final Font font, final char refChar, final CharSequence text, final float fontScale,
372 final float accel, final float velocity, final float ang_accel, final float ang_velo,
373 final LerpFunc lerp, final ShapeSetup op)
374 {
375 final Set as;
376 {
377 final List<ShapeData> allShapes = new ArrayList<ShapeData>();
378 final AABBox sourceBounds = processString(allShapes, renderModes, font, fontScale, text);
379 final GlyphShape refShape = new GlyphShape(renderModes, font, refChar, 0, 0);
380 refShape.setScale(fontScale, fontScale, 1f);
381 refShape.validate(glp);
382 pmv.pushMv();
383 {
384 refShape.applyMatToMv(pmv);
385 as = new Set(pixPerMM, refShape.getPixelPerShapeUnit(pmv, viewport, new float[2]), refShape,
386 accel, velocity, ang_accel, ang_velo, allShapes, sourceBounds, lerp);
387 }
388 pmv.popMv();
389 }
390 animSets.add(as);
391
392 for (int idx = 0; idx < as.allShapes.size(); ++idx) {
393 final ShapeData sd = as.allShapes.get(idx);
394 op.setup(as, idx, sd);
395 super.addShape(sd.shape);
396 }
397 if( DEBUG ) {
398 System.err.println("addAnimShapes: AnimSet.sourceBounds = "+as.sourceBounds);
399 }
401 return as;
402 }
403 private static final AABBox processString(final List<ShapeData> res, final int renderModes,
404 final Font font, final float fontScale, final CharSequence text)
405 {
406 final Font.GlyphVisitor fgv = new Font.GlyphVisitor() {
407 @Override
408 public void visit(final Glyph glyph, final AffineTransform t) {
409 if( !glyph.isNonContour() ) {
410 final GlyphShape gs = new GlyphShape(renderModes, glyph, t.getTranslateX(), t.getTranslateY());
411 gs.setScale(fontScale, fontScale, 1f);
412 gs.moveTo(gs.getOrigPos().x()*fontScale, gs.getOrigPos().y()*fontScale, gs.getOrigPos().z());
413 res.add( new ShapeData( gs ) );
414 }
415 }
416 };
417 return font.processString(fgv, null, text, new AffineTransform(), new AffineTransform());
418 }
419
420 /**
421 * Add a new {@link Set} with {@link ShapeData} for each {@link GlyphShape}, moving towards its target position
422 * using a fixed displacement function, defining each {@link ShapeData}'s starting position.
423 * <p>
424 * The start-position is randomly chosen within given {@link AABBox} glyphBox.
425 * </p>
426 * <p>
427 * The given {@link PMVMatrix4f} has to be setup properly for this object,
428 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
429 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
430 * </p>
431 * @param pixPerMM monitor pixel per millimeter for accurate animation
432 * @param glp used {@link GLProfile}
433 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
434 * @param viewport the int[4] viewport
435 * @param renderModes used {@link GLRegion#create(GLProfile, int, com.jogamp.opengl.util.texture.TextureSequence) region render-modes}
436 * @param font {@link Font} to be used for resulting {@link GlyphShape}s
437 * @param text the text for resulting {@link GlyphShape}s
438 * @param fontScale font scale factor for resulting {@link GlyphShape}s
439 * @param fgCol foreground color for resulting {@link GlyphShape}s
440 * @param accel translation acceleration in [m]/[s*s]
441 * @param velocity translation velocity in [m]/[s]
442 * @param ang_accel angular acceleration in [radians]/[s*s], usable for rotation etc
443 * @param ang_velo angular velocity in [radians]/[s], usable for rotation etc
444 * @param animBox {@link AABBox} denoting the maximum extend of {@link ShapeData}s start-position, also used for their x-offset
445 * @param z_only Pass true for z-only distance
446 * @param random the random float generator
447 * @param lerp {@link LerpFunc} function, see {@link AnimGroup.TargetLerp}
448 * @return newly created and added {@link Set}
449 */
450 public final Set addGlyphSetRandom01(final float pixPerMM,
451 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes,
452 final Font font, final CharSequence text, final float fontScale, final Vec4f fgCol,
453 final float accel, final float velocity, final float ang_accel, final float ang_velo,
454 final AABBox animBox, final boolean z_only, final Random random, final LerpFunc lerp)
455 {
456 return addGlyphSet(pixPerMM, glp, pmv, viewport, renderModes, font, 'X', text, fontScale,
457 accel, velocity, ang_accel, ang_velo, lerp, (final Set as, final int idx, final ShapeData sd) -> {
458 sd.shape.setColor(fgCol);
459
460 // shift targetPost to glyphBox.getMinX()
461 sd.targetPos.add(animBox.getMinX(), 0f, 0f);
462
463 final Vec3f target = sd.targetPos;
464
465 sd.startPos.set( z_only ? target.x() : animBox.getMinX() + random.nextFloat() * animBox.getWidth(),
466 z_only ? target.y() : animBox.getMinY() + random.nextFloat() * animBox.getHeight(),
467 0f + random.nextFloat() * animBox.getHeight() * 1f);
468 sd.shape.moveTo(sd.startPos);
469 } );
470 }
471
472 /**
473 * Add a new {@link Set} with {@link ShapeData} for each {@link GlyphShape}, implementing<br/>
474 * horizontal continuous scrolling while repeating the given {@code text}.
475 * <p>
476 * The given {@link PMVMatrix4f} has to be setup properly for this object,
477 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
478 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
479 * </p>
480 * @param pixPerMM monitor pixel per millimeter for accurate animation
481 * @param glp used {@link GLProfile}
482 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
483 * @param viewport the int[4] viewport
484 * @param renderModes used {@link GLRegion#create(GLProfile, int, com.jogamp.opengl.util.texture.TextureSequence) region render-modes}
485 * @param font {@link Font} to be used for resulting {@link GlyphShape}s
486 * @param text the text for resulting {@link GlyphShape}s
487 * @param fontScale font scale factor for resulting {@link GlyphShape}s
488 * @param fgCol foreground color for resulting {@link GlyphShape}s
489 * @param velocity translation velocity in [m]/[s]
490 * @param animBox {@link AABBox} denoting the maximum extend of {@link ShapeData}s start-position, also used for their x-offset
491 * @return newly created and added {@link Set}
492 */
493 public final Set addGlyphSetHorizScroll01(final float pixPerMM,
494 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes,
495 final Font font, final CharSequence text, final float fontScale, final Vec4f fgCol,
496 final float velocity, final AABBox animBox, final float y_offset)
497 {
498 return addGlyphSet(pixPerMM, glp, pmv, viewport,
499 renderModes, font, 'X', text, fontScale,
500 0f /* accel */, velocity, 0f /* ang_accel */, 0f /* 1-rotation/s */,
501 new AnimGroup.ScrollLerp(animBox),
502 (final AnimGroup.Set as, final int idx, final AnimGroup.ShapeData sd) -> {
503 sd.shape.setColor(fgCol);
504
505 sd.targetPos.set(animBox.getMinX(), y_offset, 0);
506
507 sd.startPos.set( sd.startPos.x() + animBox.getMaxX(), sd.targetPos.y(), sd.targetPos.z());
508
509 sd.shape.moveTo( sd.startPos );
510 } );
511 }
512
513 /** Sets whether {@link #tick()} shall be automatic issued on {@link #draw(GL2ES2, RegionRenderer)}, default is {@code true}. */
514 public final void setTickOnDraw(final boolean v) { tickOnDraw = v; }
515 public final boolean getTickOnDraw() { return tickOnDraw; }
516
517 /**
518 * Sets whether {@link #tick()} shall be paused, default is {@code false}.
519 * <p>
520 * Unpausing {@link #tick()} will also forward animation start-time about paused duration,
521 * as well as set last-tick timestamp to now. This prevents animation artifacts and resumes where left off.
522 * </p>
523 */
524 public final void setTickPaused(final boolean v) {
525 if( tickPaused == v ) {
526 return;
527 }
528 if( v ) {
529 tickPaused = true;
530 tpause_us = Clock.currentNanos() / 1000; // [us]
531 } else {
532 final long tnow_us = Clock.currentNanos() / 1000; // [us]
533 final long dtP_us = tnow_us - tpause_us;
534 tstart_us += dtP_us;
535 tlast_us += dtP_us;
536 tickPaused = false;
537 }
538 }
539 public final boolean getTickPaused() { return tickPaused; }
540
541 @Override
542 public void draw(final GL2ES2 gl, final RegionRenderer renderer) {
543 if( tickOnDraw && !tickPaused) {
544 tickImpl();
545 }
546 super.draw(gl, renderer);
547 }
548
549 public final void resetAnimation() {
550 tstart_us = Clock.currentNanos() / 1000; // [us]
551 tlast_us = tstart_us;
552 frame_count = 0;
553 }
554
555 public final void restartAnimation() {
556 super.runSynced( () -> {
557 for(final Set as : animSets) {
558 as.setAnimationActive(true);
559 } } );
561 }
562
563 public void stopAnimation() {
564 super.runSynced( () -> {
565 for(final Set as : animSets) {
566 as.setAnimationActive(false);
567 } } );
568 }
569
570 public final boolean isAnimationActive() {
571 for(final Set as : animSets) {
572 if( as.isAnimationActive() ) { return true; }
573 }
574 return false;
575 }
576
577 /**
578 * Issues an animation tick, usually done at {@link #draw(GL2ES2, RegionRenderer)}.
579 * @see #setTickOnDraw(boolean)
580 * @see #setTickPaused(boolean)
581 */
582 public final void tick() {
583 if( !tickPaused ) {
584 super.runSynced( () -> { tickImpl(); } );
585 }
586 }
587 private final void tickImpl() {
588 final long tnow_us = Clock.currentNanos() / 1000;
589 final float at_s = (tnow_us - tstart_us) / 1e6f;
590 final float dt_s = (tnow_us - tlast_us) / 1e6f;
591 tlast_us = tnow_us;
592 for(final Set as : animSets) {
593 if( as.isAnimationActive() ) {
594 if( !FloatUtil.isZero( as.accel ) ) {
595 as.velocity += as.accel * dt_s; // [shapeUnit]/[s]
596 as.velocity_obj += as.accel_obj * dt_s; // [shapeUnit]/[s]
597 }
598 if( !FloatUtil.isZero( as.ang_accel ) ) {
599 as.ang_velo += as.ang_accel * dt_s; // [radians]/[s]
600 }
601 for (int idx = 0; idx < as.allShapes.size(); ++idx) {
602 final ShapeData sd = as.allShapes.get(idx);
603 if( !as.lerp.eval(frame_count, as, idx, sd, at_s, dt_s) ) {
604 sd.active = false;
605 }
606 }
607 }
608 }
609 ++frame_count;
610 }
611
612 /**
613 * Default target {@link LerpFunc}, approaching {@link ShapeData}'s target position inclusive angular rotation around given normalized axis.
614 * <p>
615 * Implementation uses the current shape position and time delta since last call,
616 * hence allows rugged utilization even if shapes are dragged around.
617 * </p>
618 */
619 public static class TargetLerp implements LerpFunc {
620 final Vec3f rotAxis;
621 /**
622 * New target {@link LerpFunc} instance
623 * @param rotAxis normalized axis vector for {@link Quaternion#rotateByAngleNormalAxis(float, Vec3f)}
624 */
625 public TargetLerp(final Vec3f rotAxis) {
626 this.rotAxis = rotAxis;
627 }
628 @Override
629 public boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s) {
630 final float dxy = as.velocity_obj * dt_s; // [shapeUnit]
631 final float rot_step = as.ang_velo * dt_s; // [radians]
632 final float shapeScale = sd.shape.getScale().y();
633 final Vec3f pos = sd.shape.getPosition().copy();
634 final Vec3f p_t = sd.targetPos.minus(pos);
635 final float p_t_diff = p_t.length();
636 final Quaternion q = sd.shape.getRotation().copy();
637 final float rotAng = q.toEuler(new Vec3f()).length();
638 final float rotAngDiff = Math.min(Math.abs(rotAng), FloatUtil.TWO_PI - Math.abs(rotAng));
639 final boolean pos_ok = p_t_diff <= AnimGroup.POS_EPS;
640 final boolean pos_near = pos_ok || p_t_diff <= sd.shape.getBounds().getSize() * shapeScale * 2f;
641 final boolean rot_ok = pos_near && ( rot_step < AnimGroup.ROT_EPS || rotAngDiff <= AnimGroup.ROT_EPS || rotAngDiff <= rot_step * 2f );
642 if ( pos_ok && rot_ok ) {
643 // arrived
644 if( DEBUG ) {
645 if( 0 == idx ) {
646 System.err.println("F: dt "+(dt_s*1000f)+" ms, p_t[OK "+pos_ok+", near "+pos_near+", diff: "+p_t_diff+", dxy "+dxy+"], rot[OK "+rot_ok+", radY "+rotAng+" ("+FloatUtil.radToADeg(rotAng)+"), diff "+rotAngDiff+" ("+FloatUtil.radToADeg(rotAngDiff)+"), ang_velo "+as.ang_velo+", step "+rot_step+" ("+FloatUtil.radToADeg(rot_step)+")]");
647 }
648 }
649 sd.shape.moveTo(sd.targetPos);
650 q.setIdentity();
651 sd.shape.setRotation(q);
652 sd.shape.setInteractive(false);
653 return false;
654 }
655 if( !pos_ok ) {
656 if( DEBUG ) {
657 if( 0 == idx ) {
658 System.err.println("P: dt "+(dt_s*1000f)+" ms, p_t[OK "+pos_ok+", near "+pos_near+", diff: "+p_t_diff+", dxy "+dxy+"], rot[OK "+rot_ok+", radY "+rotAng+" ("+FloatUtil.radToADeg(rotAng)+"), diff "+rotAngDiff+" ("+FloatUtil.radToADeg(rotAngDiff)+"), ang_velo "+as.ang_velo+", step "+rot_step+" ("+FloatUtil.radToADeg(rot_step)+")]");
659 }
660 }
661 if( p_t_diff <= dxy || p_t_diff <= AnimGroup.POS_EPS ) {
662 sd.shape.moveTo(sd.targetPos);
663 } else {
664 pos.add( p_t.normalize().scale( dxy ) );
665 sd.shape.moveTo(pos);
666 }
667 if( !rot_ok ) {
668 if( pos_near ) {
669 q.rotateByAngleNormalAxis( rot_step * 2f, rotAxis );
670 } else {
671 q.rotateByAngleNormalAxis( rot_step, rotAxis );
672 }
673 sd.shape.setRotation(q);
674 }
675 } else {
676 if( DEBUG ) {
677 if( 0 == idx ) {
678 System.err.println("p: dt "+(dt_s*1000f)+" ms, p_t[OK "+pos_ok+", near "+pos_near+", diff: "+p_t_diff+", dxy "+dxy+"], rot[OK "+rot_ok+", radY "+rotAng+" ("+FloatUtil.radToADeg(rotAng)+"), diff "+rotAngDiff+" ("+FloatUtil.radToADeg(rotAngDiff)+"), ang_velo "+as.ang_velo+", step "+rot_step+" ("+FloatUtil.radToADeg(rot_step)+")]");
679 }
680 }
681 if( rot_ok || rotAngDiff <= rot_step * 3f ) {
682 q.setIdentity();
683 } else {
684 q.rotateByAngleNormalAxis( rot_step * 3f, rotAxis );
685 }
686 sd.shape.setRotation(q);
687 }
688 return true;
689 }
690 };
691
692 /**
693 * Scrolling {@link LerpFunc}, approaching {@link ShapeData}'s target position over and over.
694 * <p>
695 * Implementation uses the current shape position and time delta since last call,
696 * hence allows rugged utilization even if shapes are dragged around.
697 * </p>
698 */
699 public static class ScrollLerp implements LerpFunc {
700 final AABBox clip;
701 /**
702 * New scroller {@link LerpFunc} instance
703 * @param clip clipping box for each shape
704 */
705 public ScrollLerp(final AABBox clip) {
706 this.clip = clip;
707 }
708 @Override
709 public boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s) {
710 final float dxy = as.velocity_obj * dt_s; // [shapeUnit]
711 final Vec3f pos = sd.shape.getPosition().copy();
712 final Vec3f p_t = sd.targetPos.minus(pos);
713 final float p_t_diff = p_t.length();
714 final boolean pos_ok = p_t_diff <= dxy || p_t_diff <= AnimGroup.POS_EPS;
715 if ( pos_ok ) {
716 // arrived -> restart
717 if( 0 == idx ) {
718 as.velocity = as.start_velocity;
719 as.velocity_obj = as.start_velocity_obj;
720 as.ang_velo = as.start_ang_velo;
721 final ShapeData sd_last = as.allShapes.get(as.allShapes.size()-1);
722 final Vec3f v_thisstart_lastpos = sd_last.shape.getPosition().minus( sd.startPos );
723 final float angle_thisstart_lastpos = Vec3f.UNIT_X.angle(v_thisstart_lastpos);
724 if( angle_thisstart_lastpos >= FloatUtil.HALF_PI ) {
725 // start position of this is 'right of' current position of last: short shape-string case
726 pos.set( sd.startPos );
727 } else {
728 // start position of this is 'left of' current position of last: long shape-string case
729 pos.set( sd_last.shape.getPosition() ).add( Vec3f.UNIT_X.mul( sd_last.shape.getScaledWidth() * 2f ) );
730 }
731 // System.err.println("Scroll-0: idx "+idx+", this "+sd.shape.getPosition()+", lst "+sd_last.shape.getPosition()+", angle "+angle_thisstart_lastpos+" rad ("+FloatUtil.radToADeg(angle_thisstart_lastpos)+" deg) -> "+pos);
732 } else {
733 final ShapeData sd_pre = as.allShapes.get(idx-1);
734 final Vec3f diff_start_pre_this = sd.startPos.minus( sd_pre.startPos );
735 pos.set( sd_pre.shape.getPosition() ).add( diff_start_pre_this );
736 // System.err.println("Scroll-n: idx "+idx+", this "+sd.shape.getPosition()+", pre "+sd_pre.shape.getPosition()+" -> "+pos);
737 }
738 } else {
739 pos.add( p_t.normalize().scale( dxy ) );
740 }
741 if( clip.intersects2DRegion(pos.x(), pos.y(), sd.shape.getScaledWidth(), sd.shape.getScaledHeight()) ) {
742 sd.shape.setVisible(true);
743 } else {
744 sd.shape.setVisible(false);
745 }
746 sd.shape.moveTo(pos);
747 return true;
748 }
749 };
750
751 /**
752 * Sine target {@link LerpFunc}, approaching {@link ShapeData}'s target position utilizing the angular value for sine amplitude
753 * towards the given normalized direction vector.
754 * <p>
755 * The sine amplitude is flattened towards target.
756 * </p>
757 * <p>
758 * Implementation uses the current shape position and relative time duration since last call to interpolate,
759 * hence allows rugged utilization even if shapes are dragged around.
760 * </p>
761 */
762 public static class SineLerp implements LerpFunc {
763 final Vec3f sineDir;
764 final float sineScale;
765 final float shapeStep;
766
767 /**
768 * New sine {@link LerpFunc} instance
769 * @param sineDir normalized vector for sine amplitude direction
770 * @param sineScale sine scale factor to amplify effect
771 * @param shapeStep shape index {@code idx} factor for {@code dt_s}, amplifying angular distance between each shape. Golden ratio {@code 1.618f} reveals dynamic characteristics.
772 */
773 public SineLerp(final Vec3f sineDir, final float sineScale, final float shapeStep) {
774 this.sineDir = sineDir;
775 this.sineScale = sineScale;
776 this.shapeStep = shapeStep;
777 }
778 @Override
779 public boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s) {
780 final float dxy = as.velocity_obj * dt_s; // [shapeUnit]
781 final float angle = as.ang_velo * ( at_s + idx * shapeStep * dt_s ); // [radians]
782 final Vec3f pos = sd.shape.getPosition().copy();
783 if( 0 == frame_cnt ) {
784 sd.user = null;
785 } else if( null != sd.user ) {
786 final Vec3f lastSineVal = (Vec3f)sd.user;
787 pos.sub(lastSineVal);
788 }
789 final Vec3f p_t = sd.targetPos.minus(pos);
790 final float p_t_diff = p_t.length();
791 final boolean pos_ok = p_t_diff <= dxy || p_t_diff <= AnimGroup.POS_EPS;
792
793 if ( pos_ok ) {
794 // arrived
795 sd.shape.moveTo(sd.targetPos);
796 sd.shape.setInteractive(false);
797 return false;
798 } else {
799 final float shapeScale = sd.shape.getScale().y();
800 final float p_t_norm;
801 {
802 final Vec3f s_t = sd.targetPos.minus(sd.startPos);
803 p_t_norm = p_t_diff / s_t.length(); // [1 -> 0] from start to target
804 }
805 final float sineAmp = FloatUtil.sin(angle)*p_t_norm*shapeScale*sineScale;
806 final Vec3f sineVec = sineDir.copy().scale( sineAmp );
807 sd.user = sineVec;
808 sd.shape.moveTo( pos.add( p_t.normalize().scale( dxy ) ).add( sineVec ) );
809 }
810 return true;
811 }
812 static final boolean methodB = true;
813 };
814}
Scrolling LerpFunc, approaching ShapeData's target position over and over.
Definition: AnimGroup.java:699
boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s)
Evaluate next LERP step for the given ShapeData within the animation Set.
Definition: AnimGroup.java:709
ScrollLerp(final AABBox clip)
New scroller LerpFunc instance.
Definition: AnimGroup.java:705
Animation-Set covering its ShapeData elements, LerpFunc and animation parameter.
Definition: AnimGroup.java:98
float velocity
Current translation velocity in [m]/[s].
Definition: AnimGroup.java:115
final float accel_obj
Translation acceleration in [shapeUnit]/[s*s].
Definition: AnimGroup.java:109
final float accel
Translation acceleration in [m]/[s*s].
Definition: AnimGroup.java:107
final Vec2f pixPerShapeUnit
Pixel per shape unit.
Definition: AnimGroup.java:102
final float start_velocity_obj
Start translation velocity in [shapeUnit]/[s].
Definition: AnimGroup.java:113
void removeShape(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer, final ShapeData sd)
Removes given ShapeData from this Set and its AnimGroup.
Definition: AnimGroup.java:185
void setAnimationActive(final boolean v)
Definition: AnimGroup.java:211
ShapeData addShape(final AnimGroup g, final Shape s, final ShapeSetup op)
Adds given Shape to this Set and its AnimGroup wrapping it in ShapeData.
Definition: AnimGroup.java:169
final List< ShapeData > allShapes
All Shapes wrapped within ShapeData.
Definition: AnimGroup.java:130
float ang_velo
Current angular velocity in [radians]/[s].
Definition: AnimGroup.java:124
final Shape refShape
Reference Shape giving reference size.
Definition: AnimGroup.java:104
void removeShapes(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer)
Removes all ShapeData from this Set and its AnimGroup.
Definition: AnimGroup.java:197
final float start_ang_velo
Start angular velocity in [radians]/[s].
Definition: AnimGroup.java:122
final float start_velocity
Start translation velocity in [m]/[s].
Definition: AnimGroup.java:111
final float pixPerMM
Pixel per millimeter.
Definition: AnimGroup.java:100
final LerpFunc lerp
LerpFunc function
Definition: AnimGroup.java:127
float velocity_obj
Current translation velocity in [shapeUnit]/[s].
Definition: AnimGroup.java:117
final float ang_accel
Angular acceleration in [radians]/[s*s].
Definition: AnimGroup.java:120
final AABBox sourceBounds
Unscaled bounds of allShapes at their original position, size and rotation.
Definition: AnimGroup.java:133
Animation Shapes data covering one Shape of Set.
Definition: AnimGroup.java:75
Object user
Optional user attachment per Shape to be used within LerpFunc.
Definition: AnimGroup.java:85
ShapeData(final Shape s)
New instance with set Shape using its scaled Shape#getPosition() for startPos and targetPos.
Definition: AnimGroup.java:88
final Vec3f targetPos
Shapes scaled target position
Definition: AnimGroup.java:81
boolean active
Indicator whether the Shapes is animating or not.
Definition: AnimGroup.java:77
final Vec3f startPos
Shapes scaled start position
Definition: AnimGroup.java:79
Sine target LerpFunc, approaching ShapeData's target position utilizing the angular value for sine am...
Definition: AnimGroup.java:762
SineLerp(final Vec3f sineDir, final float sineScale, final float shapeStep)
New sine LerpFunc instance.
Definition: AnimGroup.java:773
boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s)
Evaluate next LERP step for the given ShapeData within the animation Set.
Definition: AnimGroup.java:779
Default target LerpFunc, approaching ShapeData's target position inclusive angular rotation around gi...
Definition: AnimGroup.java:619
boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s)
Evaluate next LERP step for the given ShapeData within the animation Set.
Definition: AnimGroup.java:629
TargetLerp(final Vec3f rotAxis)
New target LerpFunc instance.
Definition: AnimGroup.java:625
Group of animated Shapes including other static Shapes, optionally utilizing a Group....
Definition: AnimGroup.java:60
final void removeAnimSet(final GL2ES2 gl, final RegionRenderer renderer, final Set as)
Removes the given Set and destroys it, including its ShapeData and Shape.
Definition: AnimGroup.java:253
final boolean getTickOnDraw()
Definition: AnimGroup.java:515
final void tick()
Issues an animation tick, usually done at draw(GL2ES2, RegionRenderer).
Definition: AnimGroup.java:582
final void setTickPaused(final boolean v)
Sets whether tick() shall be paused, default is false.
Definition: AnimGroup.java:524
final void removeAllAnimSets(final GL2ES2 gl, final RegionRenderer renderer)
Removes all Sets and destroys them, including all ShapeData and their Shapes.
Definition: AnimGroup.java:245
static final float POS_EPS
Epsilon of position, 5000 x FloatUtil#EPSILON.
Definition: AnimGroup.java:63
final boolean getTickPaused()
Definition: AnimGroup.java:539
final void setTickOnDraw(final boolean v)
Sets whether tick() shall be automatic issued on draw(GL2ES2, RegionRenderer), default is true.
Definition: AnimGroup.java:514
final Set addGlyphSetRandom01(final float pixPerMM, final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes, final Font font, final CharSequence text, final float fontScale, final Vec4f fgCol, final float accel, final float velocity, final float ang_accel, final float ang_velo, final AABBox animBox, final boolean z_only, final Random random, final LerpFunc lerp)
Add a new Set with ShapeData for each GlyphShape, moving towards its target position using a fixed di...
Definition: AnimGroup.java:450
Set getAnimSet(final int idx)
Return the Set at given index or null if n/a.
Definition: AnimGroup.java:237
final void removeAnimSets(final GL2ES2 gl, final RegionRenderer renderer, final List< Set > asList)
Removes the given Sets and destroys them, including their ShapeData and Shape.
Definition: AnimGroup.java:261
AnimGroup(final Layout l)
Create a group of animated Shapes including other static Shapes w/ given Group.Layout.
Definition: AnimGroup.java:232
final Set addGlyphSet(final float pixPerMM, final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes, final Font font, final char refChar, final CharSequence text, final float fontScale, final float accel, final float velocity, final float ang_accel, final float ang_velo, final LerpFunc lerp, final ShapeSetup op)
Add a new Set with ShapeData for each GlyphShape, moving towards its target position using a generic ...
Definition: AnimGroup.java:369
Set addAnimSet(final float pixPerMM, final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final float accel, final float velocity, final float ang_accel, final float ang_velo, final LerpFunc lerp, final Shape refShape)
Add a new Set with an empty ShapeData container.
Definition: AnimGroup.java:324
final boolean isAnimationActive()
Definition: AnimGroup.java:570
static final float ROT_EPS
Epsilon of rotation [radian], 0.5 degrees or 0.008726646 radians.
Definition: AnimGroup.java:65
final Set addGlyphSetHorizScroll01(final float pixPerMM, final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes, final Font font, final CharSequence text, final float fontScale, final Vec4f fgCol, final float velocity, final AABBox animBox, final float y_offset)
Add a new Set with ShapeData for each GlyphShape, implementing horizontal continuous scrolling while...
Definition: AnimGroup.java:493
void draw(final GL2ES2 gl, final RegionRenderer renderer)
Renders the shape.
Definition: AnimGroup.java:542
Group of Shapes, optionally utilizing a Group.Layout.
Definition: Group.java:61
void addShape(final Shape s)
Adds a Shape.
Definition: Group.java:225
Shape removeShape(final Shape s)
Removes given shape, w/o Shape#destroy(GL2ES2, RegionRenderer).
Definition: Group.java:253
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
Definition: Shape.java:87
Shape setColor(final float r, final float g, final float b, final float a)
Set base color.
Definition: Shape.java:1389
final Shape setScale(final Vec3f s)
Set scale factor to given scale.
Definition: Shape.java:641
final Shape setInteractive(final boolean v)
Set whether this shape is interactive in general, i.e.
Definition: Shape.java:1711
final Vec3f getScale()
Returns scale Vec3f reference.
Definition: Shape.java:682
final Shape moveTo(final float tx, final float ty, final float tz)
Move to scaled position.
Definition: Shape.java:543
final float getScaledWidth()
Returns the scaled width of the bounding AABBox for this shape.
Definition: Shape.java:745
final float getScaledHeight()
Returns the scaled height of the bounding AABBox for this shape.
Definition: Shape.java:760
final Vec3f getPosition()
Returns position Vec3f reference, i.e.
Definition: Shape.java:587
final float[] getPixelPerShapeUnit(final int[] shapeSizePx, final float[] pixPerShape)
Retrieve pixel per scaled shape-coordinate unit, i.e.
Definition: Shape.java:1165
final AABBox getBounds()
Returns the unscaled bounding AABBox for this shape, borrowing internal instance.
Definition: Shape.java:732
final Quaternion getRotation()
Returns Quaternion for rotation.
Definition: Shape.java:595
final Shape validate(final GL2ES2 gl)
Validates the shape's underlying GLRegion.
Definition: Shape.java:850
final Shape setRotation(final Quaternion q)
Sets the rotation Quaternion.
Definition: Shape.java:604
final void destroy(final GL2ES2 gl, final RegionRenderer renderer)
Destroys all data.
Definition: Shape.java:457
final void applyMatToMv(final PMVMatrix4f pmv)
Applies the internal Matrix4f to the given modelview matrix, i.e.
Definition: Shape.java:908
final Shape setVisible(final boolean v)
Enable (default) or disable this shape's visibility.
Definition: Shape.java:363
Representing a single Font.Glyph as a GraphShape.
Definition: GlyphShape.java:53
Vec3f getOrigPos()
Returns the unscaled original position of this glyph, e.g.
Basic Float math utility functions.
Definition: FloatUtil.java:83
static final float TWO_PI
The value 2PI, i.e.
static float sin(final float a)
static float radToADeg(final float rad)
Converts radians to arc-degree.
static float adegToRad(final float arc_degree)
Converts arc-degree to radians.
static boolean isZero(final float a, final float epsilon)
Returns true if value is zero, i.e.
static final float HALF_PI
The value PI/2, i.e.
Quaternion implementation supporting Gimbal-Lock free rotations.
Definition: Quaternion.java:45
Vec3f toEuler(final Vec3f result)
Transform this quaternion to Euler rotation angles in radians (pitchX, yawY and rollZ).
Quaternion rotateByAngleNormalAxis(final float angle, final float axisX, final float axisY, final float axisZ)
Rotate this quaternion by the given angle and axis.
final Quaternion setIdentity()
Rectangle with x, y, width and height integer components.
Definition: Recti.java:34
2D Vector based upon two float components.
Definition: Vec2f.java:37
3D Vector based upon three float components.
Definition: Vec3f.java:37
Vec3f mul(final float val)
Returns this * val; creates new vector.
Definition: Vec3f.java:178
float angle(final Vec3f o)
Return the angle between two vectors in radians using Math#acos(double) on cosAngle(Vec3f).
Definition: Vec3f.java:366
Vec3f scale(final float s)
this = this * s, returns this.
Definition: Vec3f.java:218
Vec3f normalize()
Normalize this vector in place.
Definition: Vec3f.java:297
float length()
Return the length of this vector, a.k.a the norm or magnitude
Definition: Vec3f.java:283
static final Vec3f UNIT_X
Definition: Vec3f.java:39
Vec3f minus(final Vec3f arg)
Returns this - arg; creates new vector.
Definition: Vec3f.java:255
Vec3f set(final Vec3f o)
this = o, returns this.
Definition: Vec3f.java:79
Vec3f add(final float dx, final float dy, final float dz)
this = this + { dx, dy, dz }, returns this.
Definition: Vec3f.java:239
4D Vector based upon four float components.
Definition: Vec4f.java:37
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final float getWidth()
Definition: AABBox.java:879
final float getHeight()
Definition: AABBox.java:883
final float getSize()
Get the size of this AABBox where the size is represented by the length of the vector between low and...
Definition: AABBox.java:732
final AABBox resize(final AABBox newBox)
Resize the AABBox to encapsulate another AABox.
Definition: AABBox.java:274
final boolean intersects2DRegion(final float x, final float y, final float w, final float h)
Check if there is a common region between this AABBox and the passed 2D region irrespective of z rang...
Definition: AABBox.java:462
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
final PMVMatrix4f popMv()
Pop the modelview matrix from its stack.
final PMVMatrix4f pushMv()
Push the modelview matrix to its stack, while preserving its values.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
General purpose Font.Glyph visitor.
Definition: Font.java:298
boolean isNonContour()
Returns true if isWhitespace() or isUndefined().
Interface wrapper for font implementation.
Definition: Font.java:60
AABBox processString(final Font.GlyphVisitor visitor, final AffineTransform transform, final CharSequence string)
Try using processString(GlyphVisitor, AffineTransform, CharSequence, AffineTransform,...
Linear interpolation (LERP) function to evaluate the next animated frame for each ShapeData of a Set.
Definition: AnimGroup.java:290
boolean eval(long frame_cnt, Set as, final int idx, ShapeData sd, float at_s, float dt_s)
Evaluate next LERP step for the given ShapeData within the animation Set.
ShapeData setup function for animation using its enclosing Set and other data points
Definition: AnimGroup.java:276
void setup(final Set as, final int idx, final ShapeData sd)
Setting up the ShapeData for animation using its enclosing Set and other data points.
Layout for the GraphUI Group, called @ Shape#validate(GL2ES2) or Shape#validate(GLProfile).
Definition: Group.java:63