Skip to content

Commit 3a35d44

Browse files
authored
Update WireFrustum.java
1 parent c110698 commit 3a35d44

File tree

1 file changed

+108
-23
lines changed

1 file changed

+108
-23
lines changed

jme3-core/src/main/java/com/jme3/scene/debug/WireFrustum.java

Lines changed: 108 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2012 jMonkeyEngine
2+
* Copyright (c) 2009-2025 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -32,47 +32,79 @@
3232
package com.jme3.scene.debug;
3333

3434
import com.jme3.math.Vector3f;
35+
import com.jme3.renderer.Camera;
36+
import com.jme3.scene.Geometry;
3537
import com.jme3.scene.Mesh;
3638
import com.jme3.scene.VertexBuffer;
3739
import com.jme3.scene.VertexBuffer.Type;
3840
import com.jme3.scene.VertexBuffer.Usage;
41+
import com.jme3.shadow.ShadowUtil;
3942
import com.jme3.util.BufferUtils;
4043
import java.nio.FloatBuffer;
4144

45+
/**
46+
* A specialized Mesh that renders a camera frustum as a wireframe.
47+
* This class extends jME3's Mesh and is designed to visually represent
48+
* the viewing volume of a camera, which can be useful for debugging
49+
* or visualization purposes.
50+
* <p>
51+
* The frustum is defined by eight points: four for the near plane
52+
* and four for the far plane. These points are connected by lines
53+
* to form a wireframe cube-like structure.
54+
*/
4255
public class WireFrustum extends Mesh {
4356

4457
/**
45-
* This constructor is for serialization only. Do not use.
58+
* For Serialization only. Do not use.
4659
*/
4760
protected WireFrustum() {
4861
}
4962

50-
public WireFrustum(Vector3f[] points){
51-
initGeom(this, points);
52-
}
53-
54-
public static Mesh makeFrustum(Vector3f[] points){
55-
Mesh m = new Mesh();
56-
initGeom(m, points);
57-
return m;
63+
/**
64+
* Constructs a new `WireFrustum` mesh using the specified frustum corner points.
65+
* The points should represent the 8 corners of the frustum.
66+
* The expected order of points is typically:
67+
* 0-3: Near plane (e.g., bottom-left, bottom-right, top-right, top-left)
68+
* 4-7: Far plane (e.g., bottom-left, bottom-right, top-right, top-left)
69+
*
70+
* @param points An array of 8 `Vector3f` objects representing the frustum's corners.
71+
* If the array is null or does not contain 8 points, an
72+
* `IllegalArgumentException` will be thrown.
73+
*/
74+
public WireFrustum(Vector3f[] points) {
75+
if (points == null || points.length != 8) {
76+
throw new IllegalArgumentException("Frustum points array must not be null and must contain 8 points.");
77+
}
78+
setGeometryData(this, points);
5879
}
5980

60-
private static void initGeom(Mesh m, Vector3f[] points) {
61-
if (points != null)
62-
m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(points));
81+
/**
82+
* Initializes the mesh's geometric data, setting up the vertex positions and indices.
83+
* This method is called during the construction of the `WireFrustum`.
84+
*
85+
* @param points The 8 `Vector3f` points defining the frustum's corners.
86+
*/
87+
private void setGeometryData(Mesh m, Vector3f[] points) {
88+
// Set vertex positions
89+
m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(points));
6390

91+
// Set indices to draw lines connecting the frustum corners
92+
// The indices define 12 lines: 4 for near plane, 4 for far plane, and 4 connecting near to far.
6493
m.setBuffer(Type.Index, 2,
6594
new short[]{
95+
// Near plane
6696
0, 1,
6797
1, 2,
6898
2, 3,
6999
3, 0,
70100

101+
// Far plane
71102
4, 5,
72103
5, 6,
73104
6, 7,
74105
7, 4,
75106

107+
// Connecting lines (near to far)
76108
0, 4,
77109
1, 5,
78110
2, 6,
@@ -83,23 +115,76 @@ private static void initGeom(Mesh m, Vector3f[] points) {
83115
m.setMode(Mode.Lines);
84116
}
85117

86-
public void update(Vector3f[] points){
118+
/**
119+
* Updates the vertex positions of the existing `WireFrustum` mesh.
120+
* This is more efficient than creating a new `WireFrustum` instance
121+
* if only the frustum's position or orientation changes.
122+
*
123+
* @param points An array of 8 `Vector3f` objects representing the new frustum's corners.
124+
* If the array is null or does not contain 8 points, an
125+
* `IllegalArgumentException` will be thrown.
126+
*/
127+
public void update(Vector3f[] points) {
128+
if (points == null || points.length != 8) {
129+
throw new IllegalArgumentException("Frustum points array must not be null and must contain 8 points.");
130+
}
131+
87132
VertexBuffer vb = getBuffer(Type.Position);
88-
if (vb == null){
133+
if (vb == null) {
134+
// If for some reason the position buffer is missing, re-create it.
135+
// This case should ideally not happen if the object is constructed properly.
89136
setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(points));
90137
return;
91138
}
92139

93-
FloatBuffer b = BufferUtils.createFloatBuffer(points);
94-
FloatBuffer a = (FloatBuffer) vb.getData();
95-
b.rewind();
96-
a.rewind();
97-
a.put(b);
98-
a.rewind();
140+
// Create a new FloatBuffer from the updated points
141+
FloatBuffer newBuff = BufferUtils.createFloatBuffer(points);
142+
// Get the existing FloatBuffer from the VertexBuffer
143+
FloatBuffer currBuff = (FloatBuffer) vb.getData();
144+
145+
currBuff.clear(); // Clear
146+
currBuff.put(newBuff); // Copy
147+
currBuff.rewind(); // Rewind
99148

100-
vb.updateData(a);
101-
149+
// Update the VertexBuffer with the modified FloatBuffer data
150+
vb.updateData(currBuff);
151+
152+
// Update the mesh's bounding volume to reflect the new vertex positions
102153
updateBound();
103154
}
104155

156+
/**
157+
* A static factory method to create a new `WireFrustum` mesh.
158+
* This method provides a cleaner way to instantiate a `WireFrustum`.
159+
*
160+
* @param points An array of 8 `Vector3f` objects representing the frustum's corners.
161+
* @return A new `WireFrustum` instance.
162+
*/
163+
public static Mesh makeFrustum(Vector3f[] points) {
164+
return new WireFrustum(points);
165+
}
166+
167+
/**
168+
* Creates a `Geometry` object representing the wireframe frustum of a given camera.
169+
* The frustum points are calculated based on the camera's current view settings.
170+
* The returned `Geometry` can be directly attached to a scene graph.
171+
*
172+
* @param camera The `Camera` whose frustum is to be visualized.
173+
* @return A `Geometry` object containing the `WireFrustum` mesh.
174+
*/
175+
public static Geometry makeGeometry(Camera camera) {
176+
Vector3f[] frustumCorners = new Vector3f[8];
177+
for (int i = 0; i < 8; i++) {
178+
frustumCorners[i] = new Vector3f();
179+
}
180+
181+
Camera tempCam = camera.clone();
182+
tempCam.setLocation(new Vector3f(0, 0, 0));
183+
tempCam.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
184+
ShadowUtil.updateFrustumPoints2(tempCam, frustumCorners);
185+
186+
WireFrustum mesh = new WireFrustum(frustumCorners);
187+
return new Geometry("Viewing Frustum", mesh);
188+
}
189+
105190
}

0 commit comments

Comments
 (0)