Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CityDoctor
CityDoctor2
Commits
10508066
Commit
10508066
authored
Jun 19, 2026
by
Matthias Betz
Browse files
Add column-major Mat4 matrix helpers
parent
13767682
Changes
2
Show whitespace changes
Inline
Side-by-side
CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/gl/Mat4.java
0 → 100644
View file @
10508066
package
de.hft.stuttgart.citydoctor2.gui.gl
;
/**
* Minimal column-major 4x4 float matrix helpers, layout-compatible with OpenGL uniform uploads
* (element index = column*4 + row).
*/
public
final
class
Mat4
{
private
Mat4
()
{}
public
static
float
[]
identity
()
{
float
[]
m
=
new
float
[
16
];
m
[
0
]
=
m
[
5
]
=
m
[
10
]
=
m
[
15
]
=
1
f
;
return
m
;
}
public
static
float
[]
translation
(
float
x
,
float
y
,
float
z
)
{
float
[]
m
=
identity
();
m
[
12
]
=
x
;
m
[
13
]
=
y
;
m
[
14
]
=
z
;
return
m
;
}
/** Returns a * b (column-major). */
public
static
float
[]
multiply
(
float
[]
a
,
float
[]
b
)
{
float
[]
r
=
new
float
[
16
];
for
(
int
col
=
0
;
col
<
4
;
col
++)
{
for
(
int
row
=
0
;
row
<
4
;
row
++)
{
float
sum
=
0
f
;
for
(
int
k
=
0
;
k
<
4
;
k
++)
{
sum
+=
a
[
k
*
4
+
row
]
*
b
[
col
*
4
+
k
];
}
r
[
col
*
4
+
row
]
=
sum
;
}
}
return
r
;
}
/** Returns m * (x,y,z,w) as a length-4 array. */
public
static
float
[]
transform
(
float
[]
m
,
float
x
,
float
y
,
float
z
,
float
w
)
{
return
new
float
[]
{
m
[
0
]
*
x
+
m
[
4
]
*
y
+
m
[
8
]
*
z
+
m
[
12
]
*
w
,
m
[
1
]
*
x
+
m
[
5
]
*
y
+
m
[
9
]
*
z
+
m
[
13
]
*
w
,
m
[
2
]
*
x
+
m
[
6
]
*
y
+
m
[
10
]
*
z
+
m
[
14
]
*
w
,
m
[
3
]
*
x
+
m
[
7
]
*
y
+
m
[
11
]
*
z
+
m
[
15
]
*
w
};
}
public
static
float
[]
rotationX
(
float
rad
)
{
float
c
=
(
float
)
Math
.
cos
(
rad
);
float
s
=
(
float
)
Math
.
sin
(
rad
);
float
[]
m
=
identity
();
m
[
5
]
=
c
;
m
[
9
]
=
-
s
;
m
[
6
]
=
s
;
m
[
10
]
=
c
;
return
m
;
}
public
static
float
[]
rotationZ
(
float
rad
)
{
float
c
=
(
float
)
Math
.
cos
(
rad
);
float
s
=
(
float
)
Math
.
sin
(
rad
);
float
[]
m
=
identity
();
m
[
0
]
=
c
;
m
[
4
]
=
-
s
;
m
[
1
]
=
s
;
m
[
5
]
=
c
;
return
m
;
}
/** Right-handed perspective projection (camera looks down -Z). */
public
static
float
[]
perspective
(
float
fovyRad
,
float
aspect
,
float
near
,
float
far
)
{
float
f
=
(
float
)
(
1.0
/
Math
.
tan
(
fovyRad
/
2.0
));
float
[]
m
=
new
float
[
16
];
m
[
0
]
=
f
/
aspect
;
m
[
5
]
=
f
;
m
[
10
]
=
(
far
+
near
)
/
(
near
-
far
);
m
[
11
]
=
-
1
f
;
m
[
14
]
=
(
2
f
*
far
*
near
)
/
(
near
-
far
);
return
m
;
}
}
CityDoctorParent/Extensions/CityDoctorGUI/src/test/java/de/hft/stuttgart/citydoctor2/gui/gl/Mat4Test.java
0 → 100644
View file @
10508066
package
de.hft.stuttgart.citydoctor2.gui.gl
;
import
static
org
.
junit
.
Assert
.
assertArrayEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
org.junit.Test
;
public
class
Mat4Test
{
@Test
public
void
identityTimesVectorIsUnchanged
()
{
float
[]
v
=
Mat4
.
transform
(
Mat4
.
identity
(),
2
,
3
,
4
,
1
);
assertArrayEquals
(
new
float
[]{
2
,
3
,
4
,
1
},
v
,
1
e
-
6
f
);
}
@Test
public
void
translationMovesPoint
()
{
float
[]
m
=
Mat4
.
translation
(
5
,
-
2
,
1
);
float
[]
v
=
Mat4
.
transform
(
m
,
1
,
1
,
1
,
1
);
assertArrayEquals
(
new
float
[]{
6
,
-
1
,
2
,
1
},
v
,
1
e
-
6
f
);
}
@Test
public
void
multiplyIsIdentityNeutral
()
{
float
[]
t
=
Mat4
.
translation
(
1
,
2
,
3
);
assertArrayEquals
(
t
,
Mat4
.
multiply
(
Mat4
.
identity
(),
t
),
1
e
-
6
f
);
assertArrayEquals
(
t
,
Mat4
.
multiply
(
t
,
Mat4
.
identity
()),
1
e
-
6
f
);
}
@Test
public
void
rotationZ90MapsXAxisToYAxis
()
{
float
[]
m
=
Mat4
.
rotationZ
((
float
)
(
Math
.
PI
/
2
));
float
[]
v
=
Mat4
.
transform
(
m
,
1
,
0
,
0
,
1
);
assertEquals
(
0
f
,
v
[
0
],
1
e
-
6
f
);
assertEquals
(
1
f
,
v
[
1
],
1
e
-
6
f
);
}
@Test
public
void
perspectiveHasExpectedDiagonalStructure
()
{
float
[]
p
=
Mat4
.
perspective
((
float
)
Math
.
toRadians
(
60
),
1.0f
,
1
f
,
100
f
);
float
f
=
(
float
)
(
1.0
/
Math
.
tan
(
Math
.
toRadians
(
60
)
/
2
));
assertEquals
(
f
,
p
[
0
],
1
e
-
5
f
);
assertEquals
(
f
,
p
[
5
],
1
e
-
5
f
);
assertEquals
(-
1
f
,
p
[
11
],
1
e
-
6
f
);
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment