An den LOD im Editor gearbeitet
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package de.blight.game.state;
|
||||
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.AbstractControl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wählt pro Frame das passende Quad-Paar eines 8-Richtungs-Impostors.
|
||||
* Pass d wurde mit Kamera bei sin(d·2π/8), cos(d·2π/8) aufgenommen.
|
||||
* Es werden immer zwei gegenüberliegende Quads (eine Ebene) angezeigt;
|
||||
* die anderen 6 werden per CullHint.Always ausgeblendet.
|
||||
*/
|
||||
public class ImpostorViewControl extends AbstractControl {
|
||||
|
||||
private static final int DIRS = 8;
|
||||
|
||||
private Camera cam;
|
||||
|
||||
public ImpostorViewControl() {}
|
||||
|
||||
public ImpostorViewControl(Camera cam) { this.cam = cam; }
|
||||
|
||||
public void setCamera(Camera cam) { this.cam = cam; }
|
||||
|
||||
@Override
|
||||
protected void controlUpdate(float tpf) {
|
||||
if (cam == null || !(spatial instanceof Node n)) return;
|
||||
List<Spatial> quads = n.getChildren();
|
||||
int dirs = quads.size();
|
||||
if (dirs < 2) return;
|
||||
|
||||
Vector3f toCamera = cam.getLocation().subtract(spatial.getWorldTranslation());
|
||||
float dx = toCamera.x, dz = toCamera.z;
|
||||
if (Math.abs(dx) < 0.001f && Math.abs(dz) < 0.001f) return;
|
||||
|
||||
float angle = (float) Math.atan2(dx, dz);
|
||||
float t = angle * dirs / FastMath.TWO_PI;
|
||||
int best = ((int) Math.round(t) % dirs + dirs) % dirs;
|
||||
int opp = (best + dirs / 2) % dirs;
|
||||
|
||||
for (int i = 0; i < dirs; i++) {
|
||||
quads.get(i).setCullHint(i == best || i == opp
|
||||
? Spatial.CullHint.Inherit
|
||||
: Spatial.CullHint.Always);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void controlRender(RenderManager rm, ViewPort vp) {}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ import com.jme3.material.RenderState;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.scene.*;
|
||||
import com.jme3.scene.control.BillboardControl;
|
||||
import com.jme3.scene.shape.*;
|
||||
import com.jme3.texture.Texture;
|
||||
import de.blight.common.PlacedModel;
|
||||
@@ -221,11 +220,20 @@ public class WorldObjectsState extends BaseAppState {
|
||||
lodRoot.attachChild(lod2); // index 1 = lod2 (Impostor-Karte)
|
||||
treeNode.setCullHint(Spatial.CullHint.Inherit);
|
||||
lod2.setCullHint(Spatial.CullHint.Always);
|
||||
// Billboard: Impostor-Karte dreht sich immer zur Kamera,
|
||||
// unabhängig von der Baum-Rotation im BLO.
|
||||
BillboardControl bc = new BillboardControl();
|
||||
bc.setAlignment(BillboardControl.Alignment.Camera);
|
||||
lod2.addControl(bc);
|
||||
// Pivot-Korrektur: Stammbasis auf Y=0 ausrichten (Sicherungsnetz für
|
||||
// j3o-Dateien, deren 1/3-Scale-Offset nicht eingebacken wurde).
|
||||
// treeNode und lod2 gemeinsam verschieben → Geometrie und Impostor-Bild
|
||||
// bleiben deckungsgleich.
|
||||
lodRoot.updateGeometricState();
|
||||
if (treeNode.getWorldBound() instanceof com.jme3.bounding.BoundingBox treeBb) {
|
||||
float groundY = treeBb.getCenter().y - treeBb.getYExtent();
|
||||
if (Math.abs(groundY) > 0.01f) {
|
||||
treeNode.setLocalTranslation(0f, -groundY, 0f);
|
||||
lod2.setLocalTranslation(0f, -groundY, 0f);
|
||||
}
|
||||
}
|
||||
// Impostor: wählt pro Frame das kamerawinkelrichtige Quad-Paar.
|
||||
lod2.addControl(new ImpostorViewControl(app.getCamera()));
|
||||
lodRoot.addControl(new ModelLodControl(
|
||||
app.getCamera(), treeNode, null, lod2,
|
||||
m.lod1Distance() * lodFactor, m.lod2Distance() * lodFactor, m.cullDistance() * lodFactor));
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<configuration>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} %-5level [%logger{30}] %msg%n%ex</pattern>
|
||||
</encoder>
|
||||
@@ -20,6 +17,9 @@
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- LOD-Slot-Wechsel auf DEBUG aktivieren -->
|
||||
<logger name="de.blight.game.state.ModelLodControl" level="DEBUG"/>
|
||||
|
||||
<!-- JME-interne JUL-Logs auf WARN reduzieren -->
|
||||
<logger name="com.jme3" level="WARN"/>
|
||||
<!-- GltfLoader meldet bei jeder Animation "only supports linear interpolation" – bekanntes JME-Verhalten, kein Fehler -->
|
||||
|
||||
Reference in New Issue
Block a user