Skip to content

Commit d13df22

Browse files
richardTinglescenemax3d
authored andcommitted
#2275 Improve assertions for invalid transforms. (#2276)
* #2275 Improve assertions for invalid transforms. These are already caught by assertions in GLRenderer, but by that time it is unclear what call pushed in the bad values * #2275 Swap to use more generally available validation methods * #2275 Add license and javadoc * #2275 Correct copyright year * #2275 It is a quaternion
1 parent 9dbbfa7 commit d13df22

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

jme3-core/src/main/java/com/jme3/math/Quaternion.java

+23
Original file line numberDiff line numberDiff line change
@@ -1608,4 +1608,27 @@ public Quaternion clone() {
16081608
throw new AssertionError(); // can not happen
16091609
}
16101610
}
1611+
1612+
/**
1613+
* Tests whether the argument is a valid quaternion, returning false if it's
1614+
* null or if any component is NaN or infinite.
1615+
*
1616+
* @param quaternion the quaternion to test (unaffected)
1617+
* @return true if non-null and finite, otherwise false
1618+
*/
1619+
public static boolean isValidQuaternion(Quaternion quaternion) {
1620+
if (quaternion == null) {
1621+
return false;
1622+
}
1623+
if (Float.isNaN(quaternion.x)
1624+
|| Float.isNaN(quaternion.y)
1625+
|| Float.isNaN(quaternion.z)
1626+
|| Float.isNaN(quaternion.w)) {
1627+
return false;
1628+
}
1629+
return !Float.isInfinite(quaternion.x)
1630+
&& !Float.isInfinite(quaternion.y)
1631+
&& !Float.isInfinite(quaternion.z)
1632+
&& !Float.isInfinite(quaternion.w);
1633+
}
16111634
}

jme3-core/src/main/java/com/jme3/math/Transform.java

+6
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public Transform() {
121121
* @return the (modified) current instance (for chaining)
122122
*/
123123
public Transform setRotation(Quaternion rot) {
124+
assert Quaternion.isValidQuaternion(rot) : "Invalid rotation " + rot;
124125
this.rot.set(rot);
125126
return this;
126127
}
@@ -132,6 +133,7 @@ public Transform setRotation(Quaternion rot) {
132133
* @return the (modified) current instance (for chaining)
133134
*/
134135
public Transform setTranslation(Vector3f trans) {
136+
assert Vector3f.isValidVector(trans) : "Invalid translation " + trans;
135137
this.translation.set(trans);
136138
return this;
137139
}
@@ -152,6 +154,7 @@ public Vector3f getTranslation() {
152154
* @return the (modified) current instance (for chaining)
153155
*/
154156
public Transform setScale(Vector3f scale) {
157+
assert Vector3f.isValidVector(scale) : "Invalid scale " + scale;
155158
this.scale.set(scale);
156159
return this;
157160
}
@@ -163,6 +166,7 @@ public Transform setScale(Vector3f scale) {
163166
* @return the (modified) current instance (for chaining)
164167
*/
165168
public Transform setScale(float scale) {
169+
assert Float.isFinite(scale) : "Invalid scale " + scale;
166170
this.scale.set(scale, scale, scale);
167171
return this;
168172
}
@@ -286,6 +290,7 @@ public Transform combineWithParent(Transform parent) {
286290
* @return the (modified) current instance (for chaining)
287291
*/
288292
public Transform setTranslation(float x, float y, float z) {
293+
assert Float.isFinite(x) && Float.isFinite(y) && Float.isFinite(z) : "Invalid translation " + x + ", " + y + ", " + z;
289294
translation.set(x, y, z);
290295
return this;
291296
}
@@ -299,6 +304,7 @@ public Transform setTranslation(float x, float y, float z) {
299304
* @return the (modified) current instance (for chaining)
300305
*/
301306
public Transform setScale(float x, float y, float z) {
307+
assert Float.isFinite(x) && Float.isFinite(y) && Float.isFinite(z) : "Invalid scale " + x + ", " + y + ", " + z;
302308
scale.set(x, y, z);
303309
return this;
304310
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2024 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.math;
33+
34+
import junit.framework.TestCase;
35+
36+
/**
37+
* Verifies that the {@link Quaternion} class works correctly.
38+
*
39+
* @author Richard Tingle (aka Richtea)
40+
*/
41+
public class QuaternionTest extends TestCase{
42+
43+
/**
44+
* Verify that the {@link Quaternion#isValidQuaternion(com.jme3.math.Quaternion)} method works correctly. Testing
45+
* for NaNs and infinities (which are not "valid")
46+
*/
47+
public void testIsValidQuaternion(){
48+
assertFalse(Quaternion.isValidQuaternion(new Quaternion(Float.NaN, 2.1f, 3.0f, 1.5f)));
49+
assertFalse(Quaternion.isValidQuaternion(new Quaternion(1f, Float.NaN, 3.0f, 1.5f)));
50+
assertFalse(Quaternion.isValidQuaternion(new Quaternion(1f, 2.1f, Float.NaN, 1.5f)));
51+
assertFalse(Quaternion.isValidQuaternion(new Quaternion(1f, 2.1f, 3.0f, Float.NaN)));
52+
assertFalse(Quaternion.isValidQuaternion(new Quaternion(Float.POSITIVE_INFINITY, 1.5f, 1.9f, 2.0f)));
53+
assertFalse(Quaternion.isValidQuaternion(new Quaternion(Float.NEGATIVE_INFINITY, 2.5f, 8.2f, 3.0f)));
54+
assertFalse(Quaternion.isValidQuaternion(null));
55+
56+
assertTrue(Quaternion.isValidQuaternion(new Quaternion()));
57+
assertTrue(Quaternion.isValidQuaternion(new Quaternion(1.5f, -5.7f, 8.2f, 3.0f)));
58+
}
59+
}

0 commit comments

Comments
 (0)