JOGL v2.6.0
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 float fixed_frame_period = 0f;
71 private volatile float duration_s = 0;
72
73 private volatile boolean tickOnDraw = true;
74 private volatile boolean tickPaused = false;
75 private long frame_count = 0;
76
77 /** Animation {@link Shapes} data covering one {@link Shape} of {@link Set}. */
78 public static final class ShapeData {
79 /** Indicator whether the {@link Shapes} is animating or not. */
80 public boolean active;
81 /** {@link Shapes} scaled start position */
82 public final Vec3f startPos;
83 /** {@link Shapes} scaled target position */
84 public final Vec3f targetPos;
85 /** The {@link Shapes} */
86 public final Shape shape;
87 /** Optional user attachment per {@link Shape} to be used within {@link LerpFunc}. */
88 public Object user;
89
90 /** New instance with set {@link Shape} using its scaled {@link Shape#getPosition()} for {@link #startPos} and {@link #targetPos}. */
91 public ShapeData(final Shape s) {
92 active = true;
93 startPos = new Vec3f( s.getPosition() );
95 shape = s;
96 user = null;
97 }
98 }
99
100 /** Animation-Set covering its {@link ShapeData} elements, {@link LerpFunc} and animation parameter. */
101 public static final class Set {
102 /** Pixel per millimeter */
103 public final float pixPerMM;
104 /** Pixel per shape unit */
105 public final Vec2f pixPerShapeUnit;
106 /** Reference {@link Shape} giving reference size */
107 public final Shape refShape;
108
109 /** Translation acceleration in [m]/[s*s] */
110 public final float accel;
111 /** Translation acceleration in [shapeUnit]/[s*s] */
112 public final float accel_obj;
113 /** Start translation velocity in [m]/[s] */
114 public final float start_velocity;
115 /** Start translation velocity in [shapeUnit]/[s] */
116 public final float start_velocity_obj;
117 /** Current translation velocity in [m]/[s] */
118 public float velocity;
119 /** Current translation velocity in [shapeUnit]/[s] */
120 public float velocity_obj;
121
122 /** Angular acceleration in [radians]/[s*s] */
123 public final float ang_accel;
124 /** Start angular velocity in [radians]/[s] */
125 public final float start_ang_velo;
126 /** Current angular velocity in [radians]/[s] */
127 public float ang_velo;
128
129 /** {@link LerpFunc} function */
130 public final LerpFunc lerp;
131
132 /** All {@link Shape}s wrapped within {@link ShapeData}. */
133 public final List<ShapeData> allShapes;
134
135 /** Unscaled bounds of {@link #allShapes} at their original position, size and rotation. */
136 public final AABBox sourceBounds;
137
138 private Set(final float pixPerMM, final float[/*2*/] pixPerShapeUnit, final Shape refShape,
139 final float accel, final float velocity,
140 final float ang_accel, final float ang_velo,
141 final List<ShapeData> allShapes, final AABBox sourceBounds,
142 final LerpFunc lerp) {
143 this.pixPerMM = pixPerMM;
144 this.pixPerShapeUnit = new Vec2f( pixPerShapeUnit );
145 this.refShape = refShape;
146 this.accel = accel;
147 this.start_velocity = velocity;
148 this.velocity = velocity;
149 {
150 final float accel_px = accel * 1e3f * pixPerMM; // [px]/[s*s]
151 this.accel_obj = accel_px / this.pixPerShapeUnit.x(); // [shapeUnit]/[s*s]
152
153 final float velocity_px = velocity * 1e3f * pixPerMM; // [px]/[s]
154 this.start_velocity_obj = velocity_px / this.pixPerShapeUnit.x(); // [shapeUnit]/[s]
155 this.velocity_obj = this.start_velocity_obj;
156 }
157 this.ang_accel = ang_accel;
158 this.start_ang_velo = ang_velo;
159 this.ang_velo = ang_velo;
160 this.lerp = lerp;
161 this.allShapes = allShapes;
162 this.sourceBounds = sourceBounds;
163 }
164
165 /**
166 * Adds given {@link Shape} to this {@link Set} and its {@link AnimGroup} wrapping it in {@link ShapeData}.
167 * <p>
168 * Also issues {@link ShapeSetup#setup(Set, int, ShapeData)}.
169 * </p>
170 * @return newly created {@link ShapeData}
171 */
172 public ShapeData addShape(final AnimGroup g, final Shape s, final ShapeSetup op) {
173 final ShapeData sd = new ShapeData(s);
174 final int idx = this.allShapes.size();
175 this.allShapes.add( sd );
176 this.sourceBounds.resize(sd.shape.getBounds());
177 op.setup(this, idx, sd);
178 g.addShape(sd.shape);
179 return sd;
180 }
181
182 /**
183 * Removes given {@link ShapeData} from this {@link Set} and its {@link AnimGroup}.
184 * <p>
185 * Also destroys the {@link ShapeData}, including its {@link ShapeData} and their {@link Shape}.
186 * </p>
187 */
188 public void removeShape(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer, final ShapeData sd) {
189 g.removeShape(gl, renderer, sd.shape);
190 sd.active = false;
191 allShapes.remove(sd);
192 }
193
194 /**
195 * Removes all {@link ShapeData} from this {@link Set} and its {@link AnimGroup}.
196 * <p>
197 * Also destroys the {@link ShapeData}, including its {@link ShapeData} and their {@link Shape}.
198 * </p>
199 */
200 public void removeShapes(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer) {
201 for(final ShapeData sd : allShapes) {
202 g.removeShape(gl, renderer, sd.shape);
203 sd.active = false;
204 }
205 allShapes.clear();
206 }
207
208 /** Removes this {@link Set} from its {@link AnimGroup} and destroys it, including its {@link ShapeData} and their {@link Shape}. */
209 private void remove(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer) {
210 removeShapes(g, gl, renderer);
211 refShape.destroy(gl, renderer);
212 }
213
214 public void setAnimationActive(final boolean v) {
215 for(final ShapeData sd : allShapes) {
216 sd.active = v;
217 }
218 }
219 public boolean isAnimationActive() {
220 for(final ShapeData sd : allShapes) {
221 if( sd.active ) { return true; }
222 }
223 return false;
224 }
225 }
226 private final List<Set> animSets = new ArrayList<Set>();
227
228 /**
229 * Create a group of animated {@link Shape}s including other static {@link Shape}s w/ given {@link Group.Layout}.
230 * <p>
231 * Default is non-interactive, see {@link #setInteractive(boolean)}.
232 * </p>
233 * @param l optional {@link Layout}, maybe {@code null}
234 */
235 public AnimGroup(final Layout l) {
236 super(l);
237 }
238
239 /** Return the {@link Set} at given index or {@code null} if n/a. */
240 public Set getAnimSet(final int idx) {
241 if( idx < animSets.size() ) {
242 return animSets.get(idx);
243 }
244 return null;
245 }
246
247 /** Removes all {@link Set}s and destroys them, including all {@link ShapeData} and their {@link Shape}s. */
248 public final void removeAllAnimSets(final GL2ES2 gl, final RegionRenderer renderer) {
249 for(final Set as : animSets) {
250 as.remove(this, gl, renderer);
251 }
252 animSets.clear();
253 }
254
255 /** Removes the given {@link Set} and destroys it, including its {@link ShapeData} and {@link Shape}. */
256 public final void removeAnimSet(final GL2ES2 gl, final RegionRenderer renderer, final Set as) {
257 if( null != as ) {
258 as.remove(this, gl, renderer);
259 animSets.remove(as);
260 }
261 }
262
263 /** Removes the given {@link Set}s and destroys them, including their {@link ShapeData} and {@link Shape}. */
264 public final void removeAnimSets(final GL2ES2 gl, final RegionRenderer renderer, final List<Set> asList) {
265 for(final Set as : asList) {
266 if( null != as ) {
267 as.remove(this, gl, renderer);
268 animSets.remove(as);
269 }
270 }
271 }
272
273 /**
274 * {@link ShapeData} setup function for animation using its enclosing {@link Set} and other data points
275 * <p>
276 * At minimum, {@link ShapeData}'s {@link ShapeData#startPos} and {@link ShapeData#targetPos} shall be adjusted.
277 * </p>
278 */
279 public static interface ShapeSetup {
280 /**
281 * Setting up the {@link ShapeData} for animation using its enclosing {@link Set} and other data points
282 * @param as {@link Set} of the animation
283 * @param idx {@link ShapeData} index within the {@link Set#allShapes}
284 * @param sd the {@link ShapeData} matching {@code idx} containing the {@link Shape} to apply this operation
285 */
286 public void setup(final Set as, final int idx, final ShapeData sd);
287 }
288
289 /**
290 * Linear interpolation (LERP) function to evaluate the next animated frame for each {@link ShapeData} of a {@link Set}.
291 * @see AnimGroup.TargetLerp
292 */
293 public static interface LerpFunc {
294 /**
295 * Evaluate next LERP step for the given {@link ShapeData} within the animation {@link Set}.
296 * @param frame_cnt frame count for the given {@link ShapeData}
297 * @param as {@link Set} of the animation
298 * @param idx {@link ShapeData} index within the {@link Set#allShapes}
299 * @param sd the {@link ShapeData} matching {@code idx} containing the {@link Shape} to apply this operation
300 * @param at_s time delta to animation start, i.e. animation duration [s]
301 * @param dt_s time delta to last call [s]
302 * @return true if target animation shall continue, false otherwise
303 */
304 public boolean eval(long frame_cnt, Set as, final int idx, ShapeData sd, float at_s, float dt_s);
305 }
306
307 /**
308 * Add a new {@link Set} with an empty {@link ShapeData} container.
309 * <p>
310 * The given {@link PMVMatrix4f} has to be setup properly for this object,
311 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
312 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
313 * </p>
314 * @param pixPerMM monitor pixel per millimeter for accurate animation
315 * @param glp used {@link GLProfile}
316 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
317 * @param viewport the int[4] viewport
318 * @param accel translation acceleration in [m]/[s*s]
319 * @param velocity translation velocity in [m]/[s]
320 * @param ang_accel angular acceleration in [radians]/[s*s], usable for rotation etc
321 * @param ang_velo angular velocity in [radians]/[s], usable for rotation etc
322 * @param lerp {@link LerpFunc} function, see {@link AnimGroup.TargetLerp}
323 * @param refShape reference {@link Shape} giving reference size, see {@link #refShape}
324 * @param op {@link ShapeData} setup function for {@link ShapeData#startPos} and {@link ShapeData#targetPos}
325 * @return a new {@link Set} instance
326 */
327 public Set addAnimSet(final float pixPerMM,
328 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport,
329 final float accel, final float velocity,
330 final float ang_accel, final float ang_velo,
331 final LerpFunc lerp, final Shape refShape)
332 {
333 final Set as;
334 refShape.validate(glp);
335 pmv.pushMv();
336 {
337 refShape.applyMatToMv(pmv);
338 as = new Set(pixPerMM, refShape.getPixelPerShapeUnit(pmv, viewport, new float[2]), refShape,
339 accel, velocity, ang_accel, ang_velo,
340 new ArrayList<ShapeData>(), new AABBox(), lerp);
341 }
342 pmv.popMv();
343 animSets.add(as);
344 return as;
345 }
346
347 /**
348 * Add a new {@link Set} with {@link ShapeData} for each {@link GlyphShape}, moving towards its target position
349 * using a generic displacement via {@link ShapeSetup} to determine each {@link ShapeData}'s starting position.
350 * <p>
351 * The given {@link PMVMatrix4f} has to be setup properly for this object,
352 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
353 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
354 * </p>
355 * @param pixPerMM monitor pixel per millimeter for accurate animation
356 * @param glp used {@link GLProfile}
357 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
358 * @param viewport the int[4] viewport
359 * @param renderModes used {@link GLRegion#create(GLProfile, int, com.jogamp.opengl.util.texture.TextureSequence) region render-modes}
360 * @param font {@link Font} to be used for resulting {@link GlyphShape}s
361 * @param refChar reference character to calculate the reference {@link GlyphShape}
362 * @param text the text for resulting {@link GlyphShape}s
363 * @param fontScale font scale factor for resulting {@link GlyphShape}s
364 * @param accel translation acceleration in [m]/[s*s]
365 * @param velocity translation velocity in [m]/[s]
366 * @param ang_accel angular acceleration in [radians]/[s*s], usable for rotation etc
367 * @param ang_velo angular velocity in [radians]/[s], usable for rotation etc
368 * @param lerp {@link LerpFunc} function, see {@link AnimGroup.TargetLerp}
369 * @param op {@link ShapeData} setup function for {@link ShapeData#startPos} and {@link ShapeData#targetPos}
370 * @return newly created and added {@link Set}
371 */
372 public final Set addGlyphSet(final float pixPerMM,
373 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes,
374 final Font font, final char refChar, final CharSequence text, final float fontScale,
375 final float accel, final float velocity, final float ang_accel, final float ang_velo,
376 final LerpFunc lerp, final ShapeSetup op)
377 {
378 final Set as;
379 {
380 final List<ShapeData> allShapes = new ArrayList<ShapeData>();
381 final AABBox sourceBounds = processString(allShapes, renderModes, font, fontScale, text);
382 final GlyphShape refShape = new GlyphShape(renderModes, font, refChar, 0, 0);
383 refShape.setScale(fontScale, fontScale, 1f);
384 refShape.validate(glp);
385 pmv.pushMv();
386 {
387 refShape.applyMatToMv(pmv);
388 as = new Set(pixPerMM, refShape.getPixelPerShapeUnit(pmv, viewport, new float[2]), refShape,
389 accel, velocity, ang_accel, ang_velo, allShapes, sourceBounds, lerp);
390 }
391 pmv.popMv();
392 }
393 animSets.add(as);
394
395 for (int idx = 0; idx < as.allShapes.size(); ++idx) {
396 final ShapeData sd = as.allShapes.get(idx);
397 op.setup(as, idx, sd);
398 super.addShape(sd.shape);
399 }
400 if( DEBUG ) {
401 System.err.println("addAnimShapes: AnimSet.sourceBounds = "+as.sourceBounds);
402 }
404 return as;
405 }
406 private static final AABBox processString(final List<ShapeData> res, final int renderModes,
407 final Font font, final float fontScale, final CharSequence text)
408 {
409 final Font.GlyphVisitor fgv = new Font.GlyphVisitor() {
410 @Override
411 public void visit(final Glyph glyph, final AffineTransform t) {
412 if( !glyph.isNonContour() ) {
413 final GlyphShape gs = new GlyphShape(renderModes, glyph, t.getTranslateX(), t.getTranslateY());
414 gs.setScale(fontScale, fontScale, 1f);
415 gs.moveTo(gs.getOrigPos().x()*fontScale, gs.getOrigPos().y()*fontScale, gs.getOrigPos().z());
416 res.add( new ShapeData( gs ) );
417 }
418 }
419 };
420 return font.processString(fgv, null, text, new AffineTransform(), new AffineTransform());
421 }
422
423 /**
424 * Add a new {@link Set} with {@link ShapeData} for each {@link GlyphShape}, moving towards its target position
425 * using a fixed displacement function, defining each {@link ShapeData}'s starting position.
426 * <p>
427 * The start-position is randomly chosen within given {@link AABBox} glyphBox.
428 * </p>
429 * <p>
430 * The given {@link PMVMatrix4f} has to be setup properly for this object,
431 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
432 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
433 * </p>
434 * @param pixPerMM monitor pixel per millimeter for accurate animation
435 * @param glp used {@link GLProfile}
436 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
437 * @param viewport the int[4] viewport
438 * @param renderModes used {@link GLRegion#create(GLProfile, int, com.jogamp.opengl.util.texture.TextureSequence) region render-modes}
439 * @param font {@link Font} to be used for resulting {@link GlyphShape}s
440 * @param text the text for resulting {@link GlyphShape}s
441 * @param fontScale font scale factor for resulting {@link GlyphShape}s
442 * @param fgCol foreground color for resulting {@link GlyphShape}s
443 * @param accel translation acceleration in [m]/[s*s]
444 * @param velocity translation velocity in [m]/[s]
445 * @param ang_accel angular acceleration in [radians]/[s*s], usable for rotation etc
446 * @param ang_velo angular velocity in [radians]/[s], usable for rotation etc
447 * @param animBox {@link AABBox} denoting the maximum extend of {@link ShapeData}s start-position, also used for their x-offset
448 * @param z_only Pass true for z-only distance
449 * @param random the random float generator
450 * @param lerp {@link LerpFunc} function, see {@link AnimGroup.TargetLerp}
451 * @return newly created and added {@link Set}
452 */
453 public final Set addGlyphSetRandom01(final float pixPerMM,
454 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes,
455 final Font font, final CharSequence text, final float fontScale, final Vec4f fgCol,
456 final float accel, final float velocity, final float ang_accel, final float ang_velo,
457 final AABBox animBox, final boolean z_only, final Random random, final LerpFunc lerp)
458 {
459 return addGlyphSet(pixPerMM, glp, pmv, viewport, renderModes, font, 'X', text, fontScale,
460 accel, velocity, ang_accel, ang_velo, lerp, (final Set as, final int idx, final ShapeData sd) -> {
461 sd.shape.setColor(fgCol);
462
463 // shift targetPost to glyphBox.getMinX()
464 sd.targetPos.add(animBox.getMinX(), 0f, 0f);
465
466 final Vec3f target = sd.targetPos;
467
468 sd.startPos.set( z_only ? target.x() : animBox.getMinX() + random.nextFloat() * animBox.getWidth(),
469 z_only ? target.y() : animBox.getMinY() + random.nextFloat() * animBox.getHeight(),
470 0f + random.nextFloat() * animBox.getHeight() * 1f);
471 sd.shape.moveTo(sd.startPos);
472 } );
473 }
474
475 /**
476 * Add a new {@link Set} with {@link ShapeData} for each {@link GlyphShape}, implementing<br/>
477 * horizontal continuous scrolling while repeating the given {@code text}.
478 * <p>
479 * The given {@link PMVMatrix4f} has to be setup properly for this object,
480 * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene
481 * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
482 * </p>
483 * @param pixPerMM monitor pixel per millimeter for accurate animation
484 * @param glp used {@link GLProfile}
485 * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}.
486 * @param viewport the int[4] viewport
487 * @param renderModes used {@link GLRegion#create(GLProfile, int, com.jogamp.opengl.util.texture.TextureSequence) region render-modes}
488 * @param font {@link Font} to be used for resulting {@link GlyphShape}s
489 * @param text the text for resulting {@link GlyphShape}s
490 * @param fontScale font scale factor for resulting {@link GlyphShape}s
491 * @param fgCol foreground color for resulting {@link GlyphShape}s
492 * @param velocity translation velocity in [m]/[s]
493 * @param animBox {@link AABBox} denoting the maximum extend of {@link ShapeData}s start-position, also used for their x-offset
494 * @return newly created and added {@link Set}
495 */
496 public final Set addGlyphSetHorizScroll01(final float pixPerMM,
497 final GLProfile glp, final PMVMatrix4f pmv, final Recti viewport, final int renderModes,
498 final Font font, final CharSequence text, final float fontScale, final Vec4f fgCol,
499 final float velocity, final AABBox animBox, final float y_offset)
500 {
501 return addGlyphSet(pixPerMM, glp, pmv, viewport,
502 renderModes, font, 'X', text, fontScale,
503 0f /* accel */, velocity, 0f /* ang_accel */, 0f /* 1-rotation/s */,
504 new AnimGroup.ScrollLerp(animBox),
505 (final AnimGroup.Set as, final int idx, final AnimGroup.ShapeData sd) -> {
506 sd.shape.setColor(fgCol);
507
508 sd.targetPos.set(animBox.getMinX(), y_offset, 0);
509
510 sd.startPos.set( sd.startPos.x() + animBox.getMaxX(), sd.targetPos.y(), sd.targetPos.z());
511
512 sd.shape.moveTo( sd.startPos );
513 } );
514 }
515
516 /** Sets whether {@link #tick()} shall be automatic issued on {@link #draw(GL2ES2, RegionRenderer)}, default is {@code true}. */
517 public final void setTickOnDraw(final boolean v) { tickOnDraw = v; }
518 public final boolean getTickOnDraw() { return tickOnDraw; }
519
520 /**
521 * Sets whether {@link #tick()} shall be paused, default is {@code false}.
522 * <p>
523 * Unpausing {@link #tick()} will also forward animation start-time about paused duration,
524 * as well as set last-tick timestamp to now. This prevents animation artifacts and resumes where left off.
525 * </p>
526 */
527 public final void setTickPaused(final boolean v) {
528 if( tickPaused == v ) {
529 return;
530 }
531 if( v ) {
532 tickPaused = true;
533 tpause_us = Clock.currentNanos() / 1000; // [us]
534 } else {
535 final long tnow_us = Clock.currentNanos() / 1000; // [us]
536 final long dtP_us = tnow_us - tpause_us;
537 tstart_us += dtP_us;
538 tlast_us += dtP_us;
539 tickPaused = false;
540 }
541 }
542 public final boolean getTickPaused() { return tickPaused; }
543
544 @Override
545 public void draw(final GL2ES2 gl, final RegionRenderer renderer) {
546 if( tickOnDraw && !tickPaused) {
547 tickImpl();
548 }
549 super.draw(gl, renderer);
550 }
551
552 public final void resetAnimation() {
553 tstart_us = Clock.currentNanos() / 1000; // [us]
554 tlast_us = tstart_us;
555 duration_s = 0;
556 frame_count = 0;
557 }
558
559 public final void restartAnimation() {
560 super.runSynced( () -> {
561 for(final Set as : animSets) {
562 as.setAnimationActive(true);
563 } } );
565 }
566
567 public void stopAnimation() {
568 super.runSynced( () -> {
569 for(final Set as : animSets) {
570 as.setAnimationActive(false);
571 } } );
572 }
573
574 public final boolean isAnimationActive() {
575 for(final Set as : animSets) {
576 if( as.isAnimationActive() ) { return true; }
577 }
578 return false;
579 }
580
581 /**
582 * Allows setting a fixed frame period like 1f/60f. If zero (default),
583 * the actual time duration since start and delta of last frame is being used.
584 * @see #getDuration()
585 */
586 public final void setFixedPeriod(final float p) { fixed_frame_period = p; }
587 /** See {@link #setFixedPeriod(float)}. */
588 public final float getFixedPeriod() { return fixed_frame_period; }
589
590 /**
591 * Returns either the actual duration between now-start, or the fixed frame duration increment.
592 * @see #setFixedPeriod(float)
593 */
594 public final float getDuration() { return duration_s; }
595
596 /**
597 * Issues an animation tick, usually done at {@link #draw(GL2ES2, RegionRenderer)}.
598 * @see #setTickOnDraw(boolean)
599 * @see #setTickPaused(boolean)
600 * @see #getDuration()
601 * @see #setFixedPeriod(float)
602 */
603 public final void tick() {
604 if( !tickPaused ) {
605 super.runSynced( () -> { tickImpl(); } );
606 }
607 }
608 private final void tickImpl() {
609 final long tnow_us = Clock.currentNanos() / 1000;
610 final float dt_s, at_s;
611 if( FloatUtil.isZero(fixed_frame_period) ) {
612 dt_s = (tnow_us - tlast_us) / 1e6f;
613 at_s = (tnow_us - tstart_us) / 1e6f;
614 duration_s = at_s;
615 } else {
616 dt_s = fixed_frame_period;
617 duration_s += dt_s;
618 at_s = duration_s;
619 }
620 tlast_us = tnow_us;
621 for(final Set as : animSets) {
622 if( as.isAnimationActive() ) {
623 if( !FloatUtil.isZero( as.accel ) ) {
624 as.velocity += as.accel * dt_s; // [shapeUnit]/[s]
625 as.velocity_obj += as.accel_obj * dt_s; // [shapeUnit]/[s]
626 }
627 if( !FloatUtil.isZero( as.ang_accel ) ) {
628 as.ang_velo += as.ang_accel * dt_s; // [radians]/[s]
629 }
630 for (int idx = 0; idx < as.allShapes.size(); ++idx) {
631 final ShapeData sd = as.allShapes.get(idx);
632 if( !as.lerp.eval(frame_count, as, idx, sd, at_s, dt_s) ) {
633 sd.active = false;
634 }
635 }
636 }
637 }
638 ++frame_count;
639 }
640
641 /**
642 * Default target {@link LerpFunc}, approaching {@link ShapeData}'s target position inclusive angular rotation around given normalized axis.
643 * <p>
644 * Implementation uses the current shape position and time delta since last call,
645 * hence allows rugged utilization even if shapes are dragged around.
646 * </p>
647 */
648 public static class TargetLerp implements LerpFunc {
649 final Vec3f rotAxis;
650 /**
651 * New target {@link LerpFunc} instance
652 * @param rotAxis normalized axis vector for {@link Quaternion#rotateByAngleNormalAxis(float, Vec3f)}
653 */
654 public TargetLerp(final Vec3f rotAxis) {
655 this.rotAxis = rotAxis;
656 }
657 @Override
658 public boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s) {
659 final float dxy = as.velocity_obj * dt_s; // [shapeUnit]
660 final float rot_step = as.ang_velo * dt_s; // [radians]
661 final float shapeScale = sd.shape.getScale().y();
662 final Vec3f pos = sd.shape.getPosition().copy();
663 final Vec3f p_t = sd.targetPos.minus(pos);
664 final float p_t_diff = p_t.length();
665 final Quaternion q = sd.shape.getRotation().copy();
666 final float rotAng = q.toEuler(new Vec3f()).length();
667 final float rotAngDiff = Math.min(Math.abs(rotAng), FloatUtil.TWO_PI - Math.abs(rotAng));
668 final boolean pos_ok = p_t_diff <= AnimGroup.POS_EPS;
669 final boolean pos_near = pos_ok || p_t_diff <= sd.shape.getBounds().getSize() * shapeScale * 2f;
670 final boolean rot_ok = pos_near && ( rot_step < AnimGroup.ROT_EPS || rotAngDiff <= AnimGroup.ROT_EPS || rotAngDiff <= rot_step * 2f );
671 if ( pos_ok && rot_ok ) {
672 // arrived
673 if( DEBUG ) {
674 if( 0 == idx ) {
675 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)+")]");
676 }
677 }
678 sd.shape.moveTo(sd.targetPos);
679 q.setIdentity();
680 sd.shape.setRotation(q);
681 sd.shape.setInteractive(false);
682 return false;
683 }
684 if( !pos_ok ) {
685 if( DEBUG ) {
686 if( 0 == idx ) {
687 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)+")]");
688 }
689 }
690 if( p_t_diff <= dxy || p_t_diff <= AnimGroup.POS_EPS ) {
691 sd.shape.moveTo(sd.targetPos);
692 } else {
693 pos.add( p_t.normalize().scale( dxy ) );
694 sd.shape.moveTo(pos);
695 }
696 if( !rot_ok ) {
697 if( pos_near ) {
698 q.rotateByAngleNormalAxis( rot_step * 2f, rotAxis );
699 } else {
700 q.rotateByAngleNormalAxis( rot_step, rotAxis );
701 }
702 sd.shape.setRotation(q);
703 }
704 } else {
705 if( DEBUG ) {
706 if( 0 == idx ) {
707 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)+")]");
708 }
709 }
710 if( rot_ok || rotAngDiff <= rot_step * 3f ) {
711 q.setIdentity();
712 } else {
713 q.rotateByAngleNormalAxis( rot_step * 3f, rotAxis );
714 }
715 sd.shape.setRotation(q);
716 }
717 return true;
718 }
719 };
720
721 /**
722 * Scrolling {@link LerpFunc}, approaching {@link ShapeData}'s target position over and over.
723 * <p>
724 * Implementation uses the current shape position and time delta since last call,
725 * hence allows rugged utilization even if shapes are dragged around.
726 * </p>
727 */
728 public static class ScrollLerp implements LerpFunc {
729 final AABBox clip;
730 /**
731 * New scroller {@link LerpFunc} instance
732 * @param clip clipping box for each shape
733 */
734 public ScrollLerp(final AABBox clip) {
735 this.clip = clip;
736 }
737 @Override
738 public boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s) {
739 final float dxy = as.velocity_obj * dt_s; // [shapeUnit]
740 final Vec3f pos = sd.shape.getPosition().copy();
741 final Vec3f p_t = sd.targetPos.minus(pos);
742 final float p_t_diff = p_t.length();
743 final boolean pos_ok = p_t_diff <= dxy || p_t_diff <= AnimGroup.POS_EPS;
744 if ( pos_ok ) {
745 // arrived -> restart
746 if( 0 == idx ) {
747 as.velocity = as.start_velocity;
748 as.velocity_obj = as.start_velocity_obj;
749 as.ang_velo = as.start_ang_velo;
750 final ShapeData sd_last = as.allShapes.get(as.allShapes.size()-1);
751 final Vec3f v_thisstart_lastpos = sd_last.shape.getPosition().minus( sd.startPos );
752 final float angle_thisstart_lastpos = Vec3f.UNIT_X.angle(v_thisstart_lastpos);
753 if( angle_thisstart_lastpos >= FloatUtil.HALF_PI ) {
754 // start position of this is 'right of' current position of last: short shape-string case
755 pos.set( sd.startPos );
756 } else {
757 // start position of this is 'left of' current position of last: long shape-string case
758 pos.set( sd_last.shape.getPosition() ).add( Vec3f.UNIT_X.mul( sd_last.shape.getScaledWidth() * 2f ) );
759 }
760 // 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);
761 } else {
762 final ShapeData sd_pre = as.allShapes.get(idx-1);
763 final Vec3f diff_start_pre_this = sd.startPos.minus( sd_pre.startPos );
764 pos.set( sd_pre.shape.getPosition() ).add( diff_start_pre_this );
765 // System.err.println("Scroll-n: idx "+idx+", this "+sd.shape.getPosition()+", pre "+sd_pre.shape.getPosition()+" -> "+pos);
766 }
767 } else {
768 pos.add( p_t.normalize().scale( dxy ) );
769 }
770 if( clip.intersects2DRegion(pos.x(), pos.y(), sd.shape.getScaledWidth(), sd.shape.getScaledHeight()) ) {
771 sd.shape.setVisible(true);
772 } else {
773 sd.shape.setVisible(false);
774 }
775 sd.shape.moveTo(pos);
776 return true;
777 }
778 };
779
780 /**
781 * Sine target {@link LerpFunc}, approaching {@link ShapeData}'s target position utilizing the angular value for sine amplitude
782 * towards the given normalized direction vector.
783 * <p>
784 * The sine amplitude is flattened towards target.
785 * </p>
786 * <p>
787 * Implementation uses the current shape position and relative time duration since last call to interpolate,
788 * hence allows rugged utilization even if shapes are dragged around.
789 * </p>
790 */
791 public static class SineLerp implements LerpFunc {
792 final Vec3f sineDir;
793 final float sineScale;
794 final float shapeStep;
795
796 /**
797 * New sine {@link LerpFunc} instance
798 * @param sineDir normalized vector for sine amplitude direction
799 * @param sineScale sine scale factor to amplify effect
800 * @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.
801 */
802 public SineLerp(final Vec3f sineDir, final float sineScale, final float shapeStep) {
803 this.sineDir = sineDir;
804 this.sineScale = sineScale;
805 this.shapeStep = shapeStep;
806 }
807 @Override
808 public boolean eval(final long frame_cnt, final Set as, final int idx, final ShapeData sd, final float at_s, final float dt_s) {
809 final float dxy = as.velocity_obj * dt_s; // [shapeUnit]
810 final float angle = as.ang_velo * ( at_s + idx * shapeStep * dt_s ); // [radians]
811 final Vec3f pos = sd.shape.getPosition().copy();
812 if( 0 == frame_cnt ) {
813 sd.user = null;
814 } else if( null != sd.user ) {
815 final Vec3f lastSineVal = (Vec3f)sd.user;
816 pos.sub(lastSineVal);
817 }
818 final Vec3f p_t = sd.targetPos.minus(pos);
819 final float p_t_diff = p_t.length();
820 final boolean pos_ok = p_t_diff <= dxy || p_t_diff <= AnimGroup.POS_EPS;
821
822 if ( pos_ok ) {
823 // arrived
824 sd.shape.moveTo(sd.targetPos);
825 sd.shape.setInteractive(false);
826 return false;
827 } else {
828 final float shapeScale = sd.shape.getScale().y();
829 final float p_t_norm;
830 {
831 final Vec3f s_t = sd.targetPos.minus(sd.startPos);
832 p_t_norm = p_t_diff / s_t.length(); // [1 -> 0] from start to target
833 }
834 final float sineAmp = FloatUtil.sin(angle)*p_t_norm*shapeScale*sineScale;
835 final Vec3f sineVec = sineDir.copy().scale( sineAmp );
836 sd.user = sineVec;
837 sd.shape.moveTo( pos.add( p_t.normalize().scale( dxy ) ).add( sineVec ) );
838 }
839 return true;
840 }
841 static final boolean methodB = true;
842 };
843}
Scrolling LerpFunc, approaching ShapeData's target position over and over.
Definition: AnimGroup.java:728
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:738
ScrollLerp(final AABBox clip)
New scroller LerpFunc instance.
Definition: AnimGroup.java:734
Animation-Set covering its ShapeData elements, LerpFunc and animation parameter.
Definition: AnimGroup.java:101
float velocity
Current translation velocity in [m]/[s].
Definition: AnimGroup.java:118
final float accel_obj
Translation acceleration in [shapeUnit]/[s*s].
Definition: AnimGroup.java:112
final float accel
Translation acceleration in [m]/[s*s].
Definition: AnimGroup.java:110
final Vec2f pixPerShapeUnit
Pixel per shape unit.
Definition: AnimGroup.java:105
final float start_velocity_obj
Start translation velocity in [shapeUnit]/[s].
Definition: AnimGroup.java:116
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:188
void setAnimationActive(final boolean v)
Definition: AnimGroup.java:214
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:172
final List< ShapeData > allShapes
All Shapes wrapped within ShapeData.
Definition: AnimGroup.java:133
float ang_velo
Current angular velocity in [radians]/[s].
Definition: AnimGroup.java:127
final Shape refShape
Reference Shape giving reference size.
Definition: AnimGroup.java:107
void removeShapes(final AnimGroup g, final GL2ES2 gl, final RegionRenderer renderer)
Removes all ShapeData from this Set and its AnimGroup.
Definition: AnimGroup.java:200
final float start_ang_velo
Start angular velocity in [radians]/[s].
Definition: AnimGroup.java:125
final float start_velocity
Start translation velocity in [m]/[s].
Definition: AnimGroup.java:114
final float pixPerMM
Pixel per millimeter.
Definition: AnimGroup.java:103
final LerpFunc lerp
LerpFunc function
Definition: AnimGroup.java:130
float velocity_obj
Current translation velocity in [shapeUnit]/[s].
Definition: AnimGroup.java:120
final float ang_accel
Angular acceleration in [radians]/[s*s].
Definition: AnimGroup.java:123
final AABBox sourceBounds
Unscaled bounds of allShapes at their original position, size and rotation.
Definition: AnimGroup.java:136
Animation Shapes data covering one Shape of Set.
Definition: AnimGroup.java:78
Object user
Optional user attachment per Shape to be used within LerpFunc.
Definition: AnimGroup.java:88
ShapeData(final Shape s)
New instance with set Shape using its scaled Shape#getPosition() for startPos and targetPos.
Definition: AnimGroup.java:91
final Vec3f targetPos
Shapes scaled target position
Definition: AnimGroup.java:84
boolean active
Indicator whether the Shapes is animating or not.
Definition: AnimGroup.java:80
final Vec3f startPos
Shapes scaled start position
Definition: AnimGroup.java:82
Sine target LerpFunc, approaching ShapeData's target position utilizing the angular value for sine am...
Definition: AnimGroup.java:791
SineLerp(final Vec3f sineDir, final float sineScale, final float shapeStep)
New sine LerpFunc instance.
Definition: AnimGroup.java:802
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:808
Default target LerpFunc, approaching ShapeData's target position inclusive angular rotation around gi...
Definition: AnimGroup.java:648
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:658
TargetLerp(final Vec3f rotAxis)
New target LerpFunc instance.
Definition: AnimGroup.java:654
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:256
final float getDuration()
Returns either the actual duration between now-start, or the fixed frame duration increment.
Definition: AnimGroup.java:594
final boolean getTickOnDraw()
Definition: AnimGroup.java:518
final void tick()
Issues an animation tick, usually done at draw(GL2ES2, RegionRenderer).
Definition: AnimGroup.java:603
final void setTickPaused(final boolean v)
Sets whether tick() shall be paused, default is false.
Definition: AnimGroup.java:527
final void removeAllAnimSets(final GL2ES2 gl, final RegionRenderer renderer)
Removes all Sets and destroys them, including all ShapeData and their Shapes.
Definition: AnimGroup.java:248
static final float POS_EPS
Epsilon of position, 5000 x FloatUtil#EPSILON.
Definition: AnimGroup.java:63
final boolean getTickPaused()
Definition: AnimGroup.java:542
final void setTickOnDraw(final boolean v)
Sets whether tick() shall be automatic issued on draw(GL2ES2, RegionRenderer), default is true.
Definition: AnimGroup.java:517
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:453
Set getAnimSet(final int idx)
Return the Set at given index or null if n/a.
Definition: AnimGroup.java:240
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:264
AnimGroup(final Layout l)
Create a group of animated Shapes including other static Shapes w/ given Group.Layout.
Definition: AnimGroup.java:235
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:372
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:327
final boolean isAnimationActive()
Definition: AnimGroup.java:574
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:496
final void setFixedPeriod(final float p)
Allows setting a fixed frame period like 1f/60f.
Definition: AnimGroup.java:586
void draw(final GL2ES2 gl, final RegionRenderer renderer)
Renders the shape.
Definition: AnimGroup.java:545
final float getFixedPeriod()
See setFixedPeriod(float).
Definition: AnimGroup.java:588
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:293
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:279
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