Looking around the forums, the Dome class seems to be primarily viewed from the inside looking out, as a SkyDome. I need to draw a dome that is going to be looked at only from the outside - and the Dome constructor provides a way to do so (according to the javadoc) by setting "outsideView" to true.
Unfortunately, the winding for dome appears to be backwards, in all cases. When outsideView is false, and CullState(CS_BACK) is set, then the inside of the dome is culled, while the outside is not (which is the opposite of what should happen - when outsideView is false, the inside of the dome should be the "Front" not the "Back"). However, other aspects of dome - such as the lighting - are applied as if the inside but not the outside of the dome were visible. When outside view is true, the exact opposite is the case. This seemed to suggest that the winding was being applied backwards, but the lighting was not.
Going into dome and just switching which winding is used for outsideView/insideView solves the problem, as far as I can tell.
Here is a test case that should display the problem (JME1). Notice how the wrong face of the dome is culled when CS_BACK is used.
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.input.FirstPersonHandler;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Capsule;
import com.jme.scene.shape.Dome;
import com.jme.scene.state.CullState;
public class DomeLightingTest extends SimpleGame{
private Quaternion rotQuat = new Quaternion();
private float angle = 0;
private Vector3f axis = new Vector3f(1, 1, 0).normalizeLocal();
private Dome t;
private Capsule c;
/**
* Entry point for the test,
*
* @param args
*/
public static void main(String[] args) {
DomeLightingTest app = new DomeLightingTest();
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
protected void simpleUpdate() {
if (timer.getTimePerFrame() < 1) {
angle = angle + (timer.getTimePerFrame() * 1);
if (angle > 360) {
angle = 0;
}
}
rotQuat.fromAngleNormalAxis(angle, axis);
t.setLocalRotation(rotQuat);
c.setLocalRotation(rotQuat);
}
/**
* builds the trimesh.
*
* @see com.jme.app.SimpleGame#initGame()
*/
protected void simpleInitGame() {
display.setTitle("Dome Lighting Test");
t =new Dome("Dome", new Vector3f(), 30, 30, 0.5f,false);
t.setModelBound(new BoundingBox());
t.updateModelBound();
c = new Capsule("Capsule", 40, 32, 16, 0.5f, 1);
c.setModelBound(new BoundingBox());
c.updateModelBound();
c.getLocalTranslation().x -= 2;
CullState cs = display.getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
rootNode.setRenderState(cs);
input = new FirstPersonHandler(cam, 10f, 1f);
rootNode.attachChild(t);
rootNode.attachChild(c);
rootNode.updateRenderState();
c.updateRenderState();
t.updateRenderState();
lightState.setTwoSidedLighting(false);
}
}
And here is a patch (JME1)
Index: Dome.java
===================================================================
RCS file: /cvs/jme/src/com/jme/scene/shape/Dome.java,v
retrieving revision 1.11
diff -u -r1.11 Dome.java
--- Dome.java 21 Sep 2007 15:45:27 -0000 1.11
+++ Dome.java 11 Jul 2008 01:20:29 -0000
@@ -284,7 +284,7 @@
int bottomPlaneStart = (plane - 1) * (radialSamples + 1);
int topPlaneStart = plane * (radialSamples + 1);
for (int sample = 0; sample < radialSamples; sample++, index += 6) {
- if (outsideView) {
+ if (!outsideView) {
batch.getIndexBuffer().put(bottomPlaneStart + sample);
batch.getIndexBuffer().put(bottomPlaneStart + sample + 1);
batch.getIndexBuffer().put(topPlaneStart + sample);
@@ -306,7 +306,7 @@
// pole triangles
int bottomPlaneStart = (planes - 2) * (radialSamples + 1);
for (int samples = 0; samples < radialSamples; samples++, index += 3) {
- if (outsideView) {
+ if (!outsideView) {
batch.getIndexBuffer().put(bottomPlaneStart + samples);
batch.getIndexBuffer().put(bottomPlaneStart + samples + 1);
batch.getIndexBuffer().put(batch.getVertexCount() - 1);