Skip to content

Commit 16ae3d7

Browse files
Add support for global lights (#2548)
* add support for global lights * set refresh flag before light is removed * optimize global lights refresh by following only paths with RF_GLOBAL_LIGHTS flag * fix global lights refresh flag propagation * fix global lights refresh flag propagation * Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * fix * Update jme3-core/src/main/java/com/jme3/light/SpotLight.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent ecd2510 commit 16ae3d7

File tree

9 files changed

+411
-19
lines changed

9 files changed

+411
-19
lines changed

jme3-core/src/main/java/com/jme3/light/DirectionalLight.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,39 @@ public class DirectionalLight extends Light {
5959
* Creates a DirectionalLight
6060
*/
6161
public DirectionalLight() {
62+
super();
63+
}
64+
65+
/**
66+
* Creates a DirectionalLight
67+
* @param global if true, the light affects the entire tree from the root node,
68+
* otherwise it only affects the children of the node in which it is attached.
69+
*/
70+
public DirectionalLight(boolean global) {
71+
this();
72+
this.global = global;
6273
}
6374

6475
/**
6576
* Creates a DirectionalLight with the given direction
6677
* @param direction the light's direction
6778
*/
6879
public DirectionalLight(Vector3f direction) {
80+
super();
6981
setDirection(direction);
7082
}
7183

84+
/**
85+
* Creates a DirectionalLight with the given direction
86+
* @param direction the light's direction
87+
* @param global if true, the light affects the entire tree from the root node,
88+
* otherwise it only affects the children of the node in which it is attached.
89+
*/
90+
public DirectionalLight(Vector3f direction, boolean global) {
91+
this(direction);
92+
this.global = global;
93+
}
94+
7295
/**
7396
* Creates a DirectionalLight with the given direction and the given color
7497
* @param direction the light's direction
@@ -79,6 +102,19 @@ public DirectionalLight(Vector3f direction, ColorRGBA color) {
79102
setDirection(direction);
80103
}
81104

105+
/**
106+
* Creates a DirectionalLight with the given direction and the given color
107+
* @param direction the light's direction
108+
* @param color the light's color
109+
* @param global if true, the light affects the entire tree from the root node,
110+
* otherwise it only affects the children of the node in which it is attached.
111+
*/
112+
public DirectionalLight(Vector3f direction, ColorRGBA color, boolean global) {
113+
this(direction, color);
114+
this.global = global;
115+
}
116+
117+
82118
@Override
83119
public void computeLastDistance(Spatial owner) {
84120
// directional lights are after ambient lights

jme3-core/src/main/java/com/jme3/light/Light.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,39 @@ public int getId(){
116116
* The light name.
117117
*/
118118
protected String name;
119+
protected boolean global = false;
119120

120121
boolean frustumCheckNeeded = true;
121122
boolean intersectsFrustum = false;
122123

123124
protected Light() {
124125
}
125126

127+
128+
protected Light(boolean global) {
129+
this.global = global;
130+
}
131+
132+
protected Light(ColorRGBA color, boolean global) {
133+
setColor(color);
134+
this.global = global;
135+
}
136+
126137
protected Light(ColorRGBA color) {
127138
setColor(color);
128139
}
129140

141+
142+
/**
143+
* Returns true if this light affects the entire tree from the root node,
144+
* otherwise returns false, meaning it only affects the children of the node
145+
* in which it is attached.
146+
* @return true if the light is global, otherwise false.
147+
*/
148+
public boolean isGlobal() {
149+
return global;
150+
}
151+
130152
/**
131153
* Returns the color of the light.
132154
*
@@ -265,6 +287,7 @@ public void write(JmeExporter ex) throws IOException {
265287
oc.write(color, "color", null);
266288
oc.write(enabled, "enabled", true);
267289
oc.write(name, "name", null);
290+
oc.write(global, "global", false);
268291
}
269292

270293
@Override
@@ -273,6 +296,7 @@ public void read(JmeImporter im) throws IOException {
273296
color = (ColorRGBA) ic.readSavable("color", null);
274297
enabled = ic.readBoolean("enabled", true);
275298
name = ic.readString("name", null);
299+
global = ic.readBoolean("global", false);
276300
}
277301

278302
/**

jme3-core/src/main/java/com/jme3/light/LightList.java

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.jme3.util.SortUtil;
3939
import java.io.IOException;
4040
import java.util.*;
41+
import java.util.function.Predicate;
4142

4243
/**
4344
* <code>LightList</code> is used internally by {@link Spatial}s to manage
@@ -230,37 +231,53 @@ public void sort(boolean transformChanged) {
230231
* @param parent the parent's world-space LightList
231232
*/
232233
public void update(LightList local, LightList parent) {
234+
update(local, parent, null);
235+
}
236+
237+
238+
/**
239+
* Updates a "world-space" light list, using the spatial's local-space
240+
* light list, its parent's world-space light list and an optional filter.
241+
*
242+
* @param local the local-space LightList (not null)
243+
* @param parent the parent's world-space LightList
244+
* @param filter an optional filter to apply to the lights
245+
* (null means no filtering)
246+
*/
247+
public void update(LightList local, LightList parent, Predicate<Light> filter) {
233248
// clear the list as it will be reconstructed
234249
// using the arguments
235250
clear();
236251

237252
while (list.length <= local.listSize) {
238253
doubleSize();
239254
}
240-
241-
// add the lights from the local list
242-
System.arraycopy(local.list, 0, list, 0, local.listSize);
243-
for (int i = 0; i < local.listSize; i++) {
244-
// list[i] = local.list[i];
245-
distToOwner[i] = Float.NEGATIVE_INFINITY;
255+
256+
int localListSize = 0;
257+
for(int i=0;i<local.listSize;i++){
258+
Light l = local.list[i];
259+
if (filter != null && !filter.test(l)) continue;
260+
list[localListSize] = l;
261+
distToOwner[localListSize] = Float.NEGATIVE_INFINITY;
262+
localListSize++;
246263
}
247264

248265
// if the spatial has a parent node, add the lights
249266
// from the parent list as well
250267
if (parent != null) {
251-
int sz = local.listSize + parent.listSize;
268+
int sz = localListSize + parent.listSize;
252269
while (list.length <= sz)
253270
doubleSize();
254271

255272
for (int i = 0; i < parent.listSize; i++) {
256-
int p = i + local.listSize;
273+
int p = i + localListSize;
257274
list[p] = parent.list[i];
258275
distToOwner[p] = Float.NEGATIVE_INFINITY;
259276
}
260277

261-
listSize = local.listSize + parent.listSize;
278+
listSize = localListSize + parent.listSize;
262279
} else {
263-
listSize = local.listSize;
280+
listSize = localListSize;
264281
}
265282
}
266283

@@ -361,4 +378,17 @@ public void read(JmeImporter im) throws IOException {
361378

362379
Arrays.fill(distToOwner, Float.NEGATIVE_INFINITY);
363380
}
381+
382+
@Override
383+
public String toString() {
384+
StringBuilder sb = new StringBuilder("LightList[");
385+
for (int i = 0; i < listSize; i++) {
386+
sb.append(list[i]);
387+
if (i < listSize - 1) {
388+
sb.append(", ");
389+
}
390+
}
391+
sb.append("]");
392+
return sb.toString();
393+
}
364394
}

jme3-core/src/main/java/com/jme3/light/PointLight.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,38 @@ public class PointLight extends Light {
6666
* Creates a PointLight
6767
*/
6868
public PointLight() {
69+
super();
70+
}
71+
72+
/**
73+
* Creates a PointLight
74+
* @param global if true, the light affects the entire tree from the root node,
75+
* otherwise it only affects the children of the node in which it is attached.
76+
*/
77+
public PointLight(boolean global) {
78+
this();
79+
this.global = global;
6980
}
7081

7182
/**
7283
* Creates a PointLight at the given position
7384
* @param position the position in world space
7485
*/
7586
public PointLight(Vector3f position) {
87+
super();
7688
setPosition(position);
7789
}
90+
91+
/**
92+
* Creates a PointLight at the given position
93+
* @param position the position in world space
94+
* @param global if true, the light affects the entire tree from the root node,
95+
* otherwise it only affects the children of the node in which it is attached.
96+
*/
97+
public PointLight(Vector3f position, boolean global) {
98+
this(position);
99+
this.global = global;
100+
}
78101

79102
/**
80103
* Creates a PointLight at the given position and with the given color
@@ -86,6 +109,18 @@ public PointLight(Vector3f position, ColorRGBA color) {
86109
setPosition(position);
87110
}
88111

112+
/**
113+
* Creates a PointLight at the given position and with the given color
114+
* @param position the position in world space
115+
* @param color the light color
116+
* @param global if true, the light affects the entire tree from the root node,
117+
* otherwise it only affects the children of the node in which it is attached.
118+
*/
119+
public PointLight(Vector3f position, ColorRGBA color, boolean global) {
120+
this(position, color);
121+
this.global = global;
122+
}
123+
89124
/**
90125
* Creates a PointLight at the given position, with the given color and the
91126
* given radius
@@ -97,6 +132,20 @@ public PointLight(Vector3f position, ColorRGBA color, float radius) {
97132
this(position, color);
98133
setRadius(radius);
99134
}
135+
136+
/**
137+
* Creates a PointLight at the given position, with the given color and the
138+
* given radius
139+
* @param position the position in world space
140+
* @param color the light color
141+
* @param radius the light radius
142+
* @param global if true, the light affects the entire tree from the root node,
143+
* otherwise it only affects the children of the node in which it is attached.
144+
*/
145+
public PointLight(Vector3f position, ColorRGBA color, float radius, boolean global) {
146+
this(position, color, radius);
147+
this.global = global;
148+
}
100149

101150
/**
102151
* Creates a PointLight at the given position, with the given radius
@@ -107,6 +156,18 @@ public PointLight(Vector3f position, float radius) {
107156
this(position);
108157
setRadius(radius);
109158
}
159+
160+
/**
161+
* Creates a PointLight at the given position, with the given radius
162+
* @param position the position in world space
163+
* @param radius the light radius
164+
* @param global if true, the light affects the entire tree from the root node,
165+
* otherwise it only affects the children of the node in which it is attached.
166+
*/
167+
public PointLight(Vector3f position, float radius, boolean global) {
168+
this(position, radius);
169+
this.global = global;
170+
}
110171

111172
@Override
112173
public void computeLastDistance(Spatial owner) {

0 commit comments

Comments
 (0)