Skip to content

Commit 036f139

Browse files
committed
Merge branch 'spike/jmx' into spike/gaugeMap
2 parents 8bd533e + eaa7bf9 commit 036f139

File tree

10 files changed

+178
-46
lines changed

10 files changed

+178
-46
lines changed

engine/src/main/java/org/terasology/engine/rendering/logic/SkeletalMeshComponent.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ public class SkeletalMeshComponent implements VisualComponent<SkeletalMeshCompon
5555
public EntityRef rootBone = EntityRef.NULL;
5656
public float animationTime;
5757

58+
@Replicate
5859
public Vector3f scale = new Vector3f(1, 1, 1);
60+
@Replicate
5961
public Vector3f translate = new Vector3f();
6062

6163
@Replicate

engine/src/main/java/org/terasology/engine/rendering/logic/SkeletonRenderer.java

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ public void renderOpaque() {
256256
location.getWorldPosition(worldPos);
257257
float worldScale = location.getWorldScale();
258258

259-
260259
aabb = aabb.transform(new Matrix4f().translationRotateScale(worldPos, worldRot, worldScale), new AABBf());
261260

262261
//Scale bounding box for skeletalMesh.
@@ -310,9 +309,9 @@ public void renderOpaque() {
310309
} else {
311310
logger.warn("Unable to resolve bone \"{}\"", bone.getName());
312311
boneTransforms[bone.getIndex()] = new Matrix4f();
313-
314312
}
315313
}
314+
316315
((OpenGLSkeletalMesh) skeletalMesh.mesh).setScaleTranslate(skeletalMesh.scale, skeletalMesh.translate);
317316
((OpenGLSkeletalMesh) skeletalMesh.mesh).render(Arrays.asList(boneTransforms));
318317
}
@@ -329,42 +328,75 @@ public void renderOverlay() {
329328

330329
Vector3f cameraPosition = worldRenderer.getActiveCamera().getPosition();
331330

332-
Vector3f worldPos = new Vector3f();
333-
Vector3f worldPositionCameraSpace = new Vector3f();
334-
worldPos.sub(cameraPosition, worldPositionCameraSpace);
335-
Matrix4f matrixCameraSpace = new Matrix4f().translationRotateScale(worldPositionCameraSpace, new Quaternionf(), 1.0f);
336-
Matrix4f modelViewMatrix = new Matrix4f(worldRenderer.getActiveCamera().getViewMatrix()).mul(matrixCameraSpace);
337-
material.setMatrix4("projectionMatrix", worldRenderer.getActiveCamera().getProjectionMatrix());
338-
material.setMatrix4("modelViewMatrix", modelViewMatrix, true);
331+
Matrix4f relMat = new Matrix4f();
332+
Matrix4f relFinal = new Matrix4f();
333+
Matrix4f entityTransform = new Matrix4f();
334+
335+
Matrix4f result = new Matrix4f();
336+
Vector3f currentPos = new Vector3f();
339337

340338
int index = 0;
341339
for (EntityRef entity : entityManager.getEntitiesWith(SkeletalMeshComponent.class, LocationComponent.class)) {
342340
SkeletalMeshComponent skeletalMesh = entity.getComponent(SkeletalMeshComponent.class);
341+
LocationComponent locationComponent = entity.getComponent(LocationComponent.class);
343342
if (skeletalMesh.boneEntities == null) {
344343
continue;
345344
}
346345

346+
Vector3f location = locationComponent.getWorldPosition(new Vector3f());
347+
Quaternionf rotation = locationComponent.getWorldRotation(new Quaternionf());
348+
entityTransform.translationRotateScale(location, rotation, 1.0f); // transformation of the entity
349+
350+
// position is referenced around (0,0,0) (worldposition - cameraposition)
351+
Vector3f worldPositionCameraSpace = cameraPosition.negate(new Vector3f());
352+
353+
// same heightOffset is applied to worldPositionCameraSpace from #renderOpaque()
354+
// TODO: resolve repeated logic for transformation applied to bones
355+
worldPositionCameraSpace.y += skeletalMesh.heightOffset;
356+
357+
Matrix4f matrixCameraSpace = new Matrix4f().translationRotateScale(worldPositionCameraSpace, new Quaternionf(), 1.0f);
358+
Matrix4f modelViewMatrix = new Matrix4f(worldRenderer.getActiveCamera().getViewMatrix()).mul(matrixCameraSpace);
359+
material.setMatrix4("projectionMatrix", worldRenderer.getActiveCamera().getProjectionMatrix());
360+
material.setMatrix4("modelViewMatrix", modelViewMatrix, true);
361+
347362
for (Bone bone : skeletalMesh.mesh.getBones()) {
348363
Bone parentBone = bone.getParent();
349364
EntityRef boneEntity = skeletalMesh.boneEntities.get(bone.getName());
350365
if (parentBone == null) {
351366
continue;
352367
}
353368

369+
// TODO: the position of the bone is de-coupled from the actual translation/scale
354370
EntityRef boneParentEntity = skeletalMesh.boneEntities.get(parentBone.getName());
355-
356371
LocationComponent locCompA = boneEntity.getComponent(LocationComponent.class);
357372
LocationComponent locCompB = boneParentEntity.getComponent(LocationComponent.class);
358373

359-
Vector3f worldPosA = locCompA.getWorldPosition(new Vector3f());
360-
Vector3f worldPosB = locCompB.getWorldPosition(new Vector3f());
374+
// need to calculate the relative transformation from the entity to the start of the bone
375+
locCompA.getRelativeTransform(relMat.identity(), entity);
376+
// entityTransform * (scale, translation) * relativeMat * [x,y,z,1]
377+
result.set(entityTransform)
378+
.mul(relFinal.identity()
379+
.scale(skeletalMesh.scale)
380+
.translate(skeletalMesh.translate)
381+
.mul(relMat))
382+
.transformPosition(currentPos.zero()); // get the position of the start of the bone
383+
meshData.position.put(currentPos); // the start of the bone
384+
385+
// need to calculate the relative transformation from the entity to the connecting bone
386+
locCompB.getRelativeTransform(relMat.identity(), entity);
387+
// entityTransform * (scale, translation) * relativeMat * [x,y,z,1]
388+
result.set(entityTransform)
389+
.mul(relFinal
390+
.identity()
391+
.scale(skeletalMesh.scale)
392+
.translate(skeletalMesh.translate)
393+
.mul(relMat))
394+
.transformPosition(currentPos.zero()); // get the position to the connecting bone
395+
meshData.position.put(currentPos); // the end of the bone
361396

362397
meshData.color0.put(Color.white);
363398
meshData.color0.put(Color.white);
364399

365-
meshData.position.put(worldPosA);
366-
meshData.position.put(worldPosB);
367-
368400
meshData.indices.putAll(new int[]{
369401
index, index + 1
370402
});

engine/src/main/java/org/terasology/engine/rendering/nui/layers/ingame/metrics/DebugOverlay.java

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.terasology.engine.persistence.StorageManager;
1616
import org.terasology.engine.registry.In;
1717
import org.terasology.engine.rendering.nui.CoreScreenLayer;
18+
import org.terasology.engine.utilities.OperatingSystemMemory;
1819
import org.terasology.engine.world.WorldProvider;
1920
import org.terasology.engine.world.chunks.Chunks;
2021
import org.terasology.nui.databinding.ReadOnlyBinding;
@@ -31,7 +32,7 @@
3132
*/
3233
public class DebugOverlay extends CoreScreenLayer {
3334

34-
public static final double MB_SIZE = 1048576.0;
35+
public static final float MB_SIZE = 1048576.0f;
3536

3637
@In
3738
private Config config;
@@ -72,13 +73,40 @@ public Boolean get() {
7273
});
7374

7475
UILabel debugLine1 = find("debugLine1", UILabel.class);
76+
77+
// This limit doesn't change after start-up.
78+
final long dataLimit = OperatingSystemMemory.isAvailable()
79+
? OperatingSystemMemory.dataAndStackSizeLimit() : -1;
80+
7581
if (debugLine1 != null) {
76-
debugLine1.bindText(new ReadOnlyBinding<String>() {
82+
debugLine1.bindText(new ReadOnlyBinding<>() {
7783
@Override
7884
public String get() {
79-
double memoryUsage = ((double) Runtime.getRuntime().totalMemory() - (double) Runtime.getRuntime().freeMemory()) / MB_SIZE;
80-
return String.format("FPS: %.2f, Memory Usage: %.2f MB, Total Memory: %.2f MB, Max Memory: %.2f MB",
81-
time.getFps(), memoryUsage, Runtime.getRuntime().totalMemory() / MB_SIZE, Runtime.getRuntime().maxMemory() / MB_SIZE);
85+
Runtime runtime = Runtime.getRuntime();
86+
long totalHeapSize = runtime.totalMemory();
87+
float usedHeapMemory = ((float) totalHeapSize - (float) runtime.freeMemory()) / MB_SIZE;
88+
String s = String.format(
89+
"FPS: %.1f, Heap Usage: %.1f MB, Total Heap: %.1f MB, Max Heap: %.1f MB",
90+
time.getFps(),
91+
usedHeapMemory,
92+
totalHeapSize / MB_SIZE,
93+
runtime.maxMemory() / MB_SIZE
94+
);
95+
if (OperatingSystemMemory.isAvailable()) {
96+
// Check data size, because that's the one comparable to Terasology#setMemoryLimit
97+
long dataSize = OperatingSystemMemory.dataAndStackSize();
98+
// How much bigger is that than the number reported by the Java runtime?
99+
long nonJavaHeapDataSize = dataSize - totalHeapSize;
100+
String limitString = (dataLimit > 0)
101+
? String.format(" / %.1f MB (%02d%%)", dataLimit / MB_SIZE, 100 * dataSize / dataLimit)
102+
: "";
103+
return String.format(
104+
"%s, Data: %.1f MB%s, Extra: %.1f MB",
105+
s, dataSize / MB_SIZE, limitString, nonJavaHeapDataSize / MB_SIZE
106+
);
107+
} else {
108+
return s;
109+
}
82110
}
83111
});
84112
}
@@ -158,7 +186,7 @@ public String get() {
158186
debugInfo.bindText(new ReadOnlyBinding<String>() {
159187
@Override
160188
public String get() {
161-
return String.format("[H] : Debug Documentation");
189+
return "[H] : Debug Documentation";
162190
}
163191
});
164192
}

engine/src/main/java/org/terasology/engine/rendering/nui/layers/ingame/metrics/MetricsMode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ public MetricsMode(String name) {
4545
*/
4646
public abstract boolean isAvailable();
4747

48-
public abstract boolean isPerformanceManagerMode();
48+
public boolean isPerformanceManagerMode() {
49+
return false;
50+
}
4951

5052
/**
5153
* A (human readable) name for the metrics mode.

engine/src/main/java/org/terasology/engine/rendering/nui/layers/ingame/metrics/NetworkStatsMode.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,4 @@ public String getMetrics() {
5050
public boolean isAvailable() {
5151
return networkSystem.getMode() != NetworkMode.NONE;
5252
}
53-
54-
@Override
55-
public boolean isPerformanceManagerMode() {
56-
return false;
57-
}
5853
}

engine/src/main/java/org/terasology/engine/rendering/nui/layers/ingame/metrics/NullMetricsMode.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,4 @@ public String getMetrics() {
1717
public boolean isAvailable() {
1818
return true;
1919
}
20-
21-
@Override
22-
public boolean isPerformanceManagerMode() {
23-
return false;
24-
}
2520
}

engine/src/main/java/org/terasology/engine/rendering/nui/layers/ingame/metrics/RunningThreadsMode.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,4 @@ public String getMetrics() {
3030
public boolean isAvailable() {
3131
return true;
3232
}
33-
34-
@Override
35-
public boolean isPerformanceManagerMode() {
36-
return false;
37-
}
3833
}

engine/src/main/java/org/terasology/engine/rendering/nui/layers/ingame/metrics/WorldRendererMode.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,4 @@ public String getMetrics() {
2020
public boolean isAvailable() {
2121
return CoreRegistry.get(WorldRenderer.class) != null;
2222
}
23-
24-
@Override
25-
public boolean isPerformanceManagerMode() {
26-
return false;
27-
}
2823
}

engine/src/main/java/org/terasology/engine/rendering/opengl/OpenGLSkeletalMesh.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,11 @@ public void doRender(List<Vector3f> verts, List<Vector3f> normals) {
140140
}
141141

142142
public void render() {
143-
// preRender();
144143
doRender(data.getBindPoseVertexPositions(), data.getBindPoseVertexNormals());
145-
// postRender();
146144
}
147145

148146
public void render(List<Matrix4f> boneTransforms) {
149-
// preRender();
150147
doRender(data.getVertexPositions(boneTransforms), data.getVertexNormals(boneTransforms));
151-
// postRender();
152148
}
153149

154150
@Override
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2021 The Terasology Foundation
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package org.terasology.engine.utilities;
5+
6+
import com.sun.jna.platform.unix.LibC;
7+
8+
import java.io.IOException;
9+
import java.io.UncheckedIOException;
10+
import java.nio.file.Files;
11+
import java.nio.file.Path;
12+
13+
/**
14+
* Monitor process memory usage.
15+
* <p>
16+
* This checks process's total memory usage as seen by the operating system.
17+
* This includes memory not managed by the JVM.
18+
*/
19+
public final class OperatingSystemMemory {
20+
public static final int PAGE_SIZE = 1 << 12; // 4 kB on x86 platforms
21+
22+
private static final Path PROC_STATM = Path.of("/proc/self/statm");
23+
24+
private OperatingSystemMemory() { }
25+
26+
public static boolean isAvailable() {
27+
return OS.IS_LINUX;
28+
}
29+
30+
public static long residentSetSize() {
31+
try {
32+
return STATM.RESIDENT.inBytes(Files.readString(PROC_STATM));
33+
} catch (IOException e) {
34+
throw new UncheckedIOException(e);
35+
}
36+
}
37+
38+
public static long dataAndStackSize() {
39+
try {
40+
return STATM.DATA.inBytes(Files.readString(PROC_STATM));
41+
} catch (IOException e) {
42+
throw new UncheckedIOException(e);
43+
}
44+
}
45+
46+
public static long dataAndStackSizeLimit() {
47+
final LibC.Rlimit dataLimit = new LibC.Rlimit();
48+
LibC.INSTANCE.getrlimit(LibC.RLIMIT_DATA, dataLimit);
49+
return dataLimit.rlim_cur;
50+
}
51+
52+
/**
53+
* The fields of /proc/[pid]/statm
54+
* <p>
55+
* Note from proc(5):
56+
* <blockquote><p>
57+
* Some of these values are inaccurate because of a kernel-internal scalability optimization.
58+
* If accurate values are required, use /proc/[pid]/smaps or /proc/[pid]/smaps_rollup instead,
59+
* which are much slower but provide accurate, detailed information.
60+
* </p></blockquote>
61+
*/
62+
enum STATM {
63+
/** total program size */
64+
SIZE(0),
65+
/** resident set size */
66+
RESIDENT(1),
67+
/** number of resident shared pages */
68+
SHARED(2),
69+
/** text (code) */
70+
TEXT(3),
71+
/** unused since Linux 2.6 */
72+
LIB(4),
73+
/** data + stack */
74+
DATA(5),
75+
/** unused since Linux 2.6 */
76+
DT(6);
77+
78+
private final short index;
79+
80+
STATM(int i) {
81+
index = (short) i;
82+
}
83+
84+
public long rawValue(String line) {
85+
return Long.parseLong(line.split(" ")[index]);
86+
}
87+
88+
public long inBytes(String line) {
89+
return rawValue(line) * PAGE_SIZE;
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)