Hi,
I don’t know how to continue.
I tested my code with swing and custom painting (2D of cause). When everything was fine, I transformed the code to jme3 and 3D.
But result is completely different, although I use the same code.
May be I have overlooked something, but I have no idea about it.
As a test image I tried to create a lower case letter “N”, which looks ok from swing …
same code run by jme3:
Here is the code …
first the Application class
package de.schwarzrot.jme3;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.jayfella.camera.FocusCameraState;
import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.debug.Arrow;
import de.schwarzrot.util.IGeoLineParser;
import de.schwarzrot.widgets.jme3.Arc;
import de.schwarzrot.widgets.jme3.ICreator3D;
import de.schwarzrot.widgets.jme3.Line;
public class Preview3DCreator extends SimpleApplication implements ICreator3D {
public Preview3DCreator() {
geoCache = new HashMap<Integer, Geometry>();
}
@Override
public void createArc(Vector3f from, Vector3f to, Vector3f center, int lineNum, boolean clockwise) {
Arc a = new Arc(from, to, center, lineNum, clockwise);
Geometry ga = new Geometry("Arc", a);
Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
m.setColor("Color", ColorRGBA.White);
m.getAdditionalRenderState().setLineWidth(2);
ga.setMaterial(m);
geoCache.put(lineNum, ga);
rootNode.attachChild(ga);
}
@Override
public void createLine(Vector3f from, Vector3f to, int lineNum, boolean fastMove) {
Line l = new Line(from, to, lineNum, fastMove);
Geometry gl = new Geometry("Line", l);
Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
m.setColor("Color", fastMove ? ColorRGBA.Gray : ColorRGBA.White);
m.getAdditionalRenderState().setLineWidth(fastMove ? 1 : 2);
gl.setMaterial(m);
geoCache.put(lineNum, gl);
rootNode.attachChild(gl);
}
public void processGeomFile(File f) {
BufferedReader br = null;
Vector3f last = null;
String line;
wait4Material();
try {
br = new BufferedReader(new FileReader(f));
while ((line = br.readLine()) != null) {
last = geoParser.parseLine(line, last, this);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ex) {
}
}
updateCamera();
}
}
public void setGeoParser(IGeoLineParser p) {
this.geoParser = p;
}
@Override
public void simpleInitApp() {
setDisplayFps(false);
setDisplayStatView(false);
setShowSettings(false);
flyCam.setEnabled(false);
Geometry geo = createOrigin();
focusCameraState = new FocusCameraState();
stateManager.attach(focusCameraState);
focusCameraState.setFocusPoint(geo);
}
// creation of graphic primitives is too early, so have to wait for material
// to become available
public void wait4Material() {
Material m = null;
while (m == null) {
Thread.yield();
try {
Thread.sleep(100, 0);
} catch (InterruptedException e) {
}
if (assetManager != null) {
m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
}
}
}
protected Geometry createOrigin() {
Arrow a = new Arrow(new Vector3f(1f, 0, 0));
Geometry ga = new Geometry("Arrow", a);
Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
m.setColor("Color", ColorRGBA.Red);
m.getAdditionalRenderState().setWireframe(true);
m.getAdditionalRenderState().setLineWidth(1);
ga.setMaterial(m);
rootNode.attachChild(ga);
a = new Arrow(new Vector3f(0, 1f, 0));
ga = new Geometry("Arrow", a);
m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
m.setColor("Color", ColorRGBA.Green);
m.getAdditionalRenderState().setWireframe(true);
m.getAdditionalRenderState().setLineWidth(1);
ga.setMaterial(m);
rootNode.attachChild(ga);
a = new Arrow(new Vector3f(0, 0, 1f));
ga = new Geometry("Arrow", a);
m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
m.setColor("Color", ColorRGBA.Blue);
m.getAdditionalRenderState().setWireframe(true);
m.getAdditionalRenderState().setLineWidth(1);
ga.setMaterial(m);
rootNode.attachChild(ga);
return ga;
}
protected void reset() {
rootNode.detachAllChildren();
createOrigin();
}
// code from 1000ml
private void updateCamera() {
BoundingBox bbox = (BoundingBox) rootNode.getWorldBound();
if (bbox == null)
return;
float extent = bbox.getXExtent();
if (bbox.getYExtent() > extent)
extent = bbox.getYExtent();
if (bbox.getZExtent() > extent)
extent = bbox.getZExtent();
/*
* Calculate camera distance where BoundingBox is fully visible
*/
float dist = extent / (float) Math.tan(s_camFov * 0.5 * FastMath.DEG_TO_RAD);
cam.setLocation(new Vector3f(0, dist * (float) Math.sin(s_camElevation),
dist * (float) Math.cos(s_camElevation)));
float y = bbox.getCenter().y * 0.666f;
cam.lookAt(new Vector3f(0, y, 0), Vector3f.UNIT_Y);
}
private IGeoLineParser geoParser;
private FocusCameraState focusCameraState;
private Map<Integer, Geometry> geoCache;
private static final float s_camFov = 30;
private static final float s_camElevation = 40 * FastMath.DEG_TO_RAD;
}
which is embedded in a Swing panel like this:
(this Panel contains the test-data)
package de.schwarzrot.jme3;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import com.jme3.app.SimpleApplication;
import com.jme3.math.Vector3f;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.util.JmeFormatter;
import de.schwarzrot.widgets.jme3.ICreator3D;
public class JME3Pane extends JPanel {
public JME3Pane(SimpleApplication app) {
AppSettings settings = new AppSettings(true);
settings.setWidth(1000);
settings.setHeight(1000);
JME3Pane.app = app;
app.setPauseOnLostFocus(false);
app.setSettings(settings);
app.createCanvas();
app.startCanvas();
context = (JmeCanvasContext) app.getContext();
canvas = context.getCanvas();
canvas.setSize(settings.getWidth(), settings.getHeight());
setLayout(new BorderLayout());
add(canvas, BorderLayout.CENTER);
}
protected void createPrimitives(ICreator3D app) {
app.wait4Material();
app.createLine(new Vector3f(13.279f, 0.250f, 3.000f), new Vector3f(13.279f, 0.250f, -5.000f), 330,
false);
app.createLine(new Vector3f(13.279f, 0.250f, -5.000f), new Vector3f(14.797f, 7.510f, -5.000f), 340,
false);
app.createLine(new Vector3f(14.797f, 7.510f, -5.000f), new Vector3f(16.656f, 7.510f, -5.000f), 350,
false);
app.createLine(new Vector3f(16.656f, 7.510f, -5.000f), new Vector3f(16.465f, 6.566f, -5.000f), 360,
false);
app.createArc(new Vector3f(16.465f, 6.566f, -5.000f), new Vector3f(17.082f, 7.043f, -5.000f),
new Vector3f(20.876f, 1.496f, -5.000f), 370, true);
app.createArc(new Vector3f(17.082f, 7.043f, -5.000f), new Vector3f(17.764f, 7.421f, -5.000f),
new Vector3f(19.351f, 3.751f, -5.000f), 380, true);
app.createArc(new Vector3f(17.764f, 7.421f, -5.000f), new Vector3f(19.042f, 7.681f, -5.000f),
new Vector3f(19.031f, 4.458f, -5.000f), 390, true);
app.createArc(new Vector3f(19.042f, 7.681f, -5.000f), new Vector3f(19.798f, 7.568f, -5.000f),
new Vector3f(19.074f, 5.306f, -5.000f), 400, true);
app.createArc(new Vector3f(19.798f, 7.568f, -5.000f), new Vector3f(20.450f, 7.168f, -5.000f),
new Vector3f(19.284f, 5.997f, -5.000f), 410, true);
app.createArc(new Vector3f(20.450f, 7.168f, -5.000f), new Vector3f(20.851f, 6.542f, -5.000f),
new Vector3f(19.285f, 5.981f, -5.000f), 420, true);
app.createArc(new Vector3f(20.851f, 6.542f, -5.000f), new Vector3f(20.970f, 5.808f, -5.000f),
new Vector3f(18.815f, 5.836f, -5.000f), 430, true);
app.createArc(new Vector3f(20.970f, 5.808f, -5.000f), new Vector3f(20.885f, 5.079f, -5.000f),
new Vector3f(15.882f, 6.033f, -5.000f), 440, true);
app.createArc(new Vector3f(20.885f, 5.079f, -5.000f), new Vector3f(20.744f, 4.358f, -5.000f),
new Vector3f(1.159f, 8.548f, -5.000f), 450, true);
app.createLine(new Vector3f(20.744f, 4.358f, -5.000f), new Vector3f(19.890f, 0.250f, -5.000f), 460,
false);
app.createLine(new Vector3f(19.890f, 0.250f, -5.000f), new Vector3f(17.928f, 0.250f, -5.000f), 470,
false);
app.createLine(new Vector3f(17.928f, 0.250f, -5.000f), new Vector3f(18.789f, 4.372f, -5.000f), 480,
false);
app.createArc(new Vector3f(18.789f, 4.372f, -5.000f), new Vector3f(18.898f, 4.920f, -5.000f),
new Vector3f(-12.620f, 10.920f, -5.000f), 490, false);
app.createArc(new Vector3f(18.898f, 4.920f, -5.000f), new Vector3f(18.980f, 5.473f, -5.000f),
new Vector3f(14.072f, 5.920f, -5.000f), 500, false);
app.createArc(new Vector3f(18.980f, 5.473f, -5.000f), new Vector3f(18.755f, 6.061f, -5.000f),
new Vector3f(18.210f, 5.514f, -5.000f), 510, false);
app.createArc(new Vector3f(18.755f, 6.061f, -5.000f), new Vector3f(18.140f, 6.279f, -5.000f),
new Vector3f(18.188f, 5.441f, -5.000f), 520, false);
app.createArc(new Vector3f(18.140f, 6.279f, -5.000f), new Vector3f(17.634f, 6.169f, -5.000f),
new Vector3f(18.166f, 4.950f, -5.000f), 530, false);
app.createArc(new Vector3f(17.634f, 6.169f, -5.000f), new Vector3f(17.183f, 5.917f, -5.000f),
new Vector3f(18.612f, 3.881f, -5.000f), 540, false);
app.createArc(new Vector3f(17.183f, 5.917f, -5.000f), new Vector3f(16.355f, 4.960f, -5.000f),
new Vector3f(18.615f, 3.843f, -5.000f), 550, false);
app.createArc(new Vector3f(16.355f, 4.960f, -5.000f), new Vector3f(16.066f, 4.108f, -5.000f),
new Vector3f(20.738f, 2.998f, -5.000f), 560, false);
app.createArc(new Vector3f(16.066f, 4.108f, -5.000f), new Vector3f(15.863f, 3.230f, -5.000f),
new Vector3f(34.239f, -0.562f, -5.000f), 570, false);
app.createLine(new Vector3f(15.863f, 3.230f, -5.000f), new Vector3f(15.241f, 0.250f, -5.000f), 580,
false);
app.createLine(new Vector3f(15.241f, 0.250f, -5.000f), new Vector3f(13.279f, 0.250f, -5.000f), 590,
false);
}
public static void main(String[] args) {
JmeFormatter formatter = new JmeFormatter();
Handler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
Logger.getLogger("").addHandler(consoleHandler);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
boolean simpleTest = false;
createFrame();
if (simpleTest) {
JME3Pane pane3DCanvas = new JME3Pane(new LineWidthTest());
frame.add(pane3DCanvas, BorderLayout.CENTER);
} else {
Preview3DCreator app = new Preview3DCreator();
final JME3Pane pane3DCanvas = new JME3Pane(app);
frame.add(pane3DCanvas, BorderLayout.CENTER);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
pane3DCanvas.createPrimitives(app);
}
});
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private static void createFrame() {
frame = new JFrame("Test JME3-Integration");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
app.stop();
}
});
}
private static final long serialVersionUID = 1L;
private static SimpleApplication app;
private static JmeCanvasContext context;
private static Canvas canvas;
private static JFrame frame;
}
and here is the point of interest, my implementation of an arc:
package de.schwarzrot.widgets.jme3;
import java.nio.FloatBuffer;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils;
public class Arc extends Mesh {
// based on the work of Lim, YongHoon
public Arc(Vector3f from, Vector3f to, Vector3f center, int lineNum, boolean clockwise) {
FloatBuffer vertexBuf = createBuffer(from, to, center);
this.lineNum = lineNum;
this.clockwise = clockwise;
setBuffer(Type.Position, 3, vertexBuf);
setMode(Mode.LineStrip);
updateBound();
updateCounts();
}
public int getLineNum() {
return lineNum;
}
public boolean isClockwise() {
return clockwise;
}
private FloatBuffer createBuffer(Vector3f from, Vector3f to, Vector3f center) {
Vector3f base = new Vector3f(1, 0, 0);
Vector3f s = from.subtract(center);
Vector3f e = to.subtract(center);
float r = s.length();
// float r1 = e.length();
s.normalizeLocal();
e.normalizeLocal();
float a0 = base.angleBetween(s);
float a1 = base.angleBetween(e);
if (s.y > center.y)
a0 = FastMath.TWO_PI - a0;
if (e.y > center.y)
a1 = FastMath.TWO_PI - a1;
float arc = a1 - a0;
if (!clockwise && a0 < a1)
arc = FastMath.TWO_PI - arc;
else if (clockwise && a0 > a1)
arc = FastMath.TWO_PI - a0 + a1;
float step = arc / samples;
float zStep = (to.z - from.z) / samples;
float x = 0, y = 0, z = from.getZ(), theta = a0;
FloatBuffer buf = BufferUtils.createVector3Buffer(samples + 1);
if (!clockwise && step > 0)
step *= -1;
buf.rewind();
for (int i = 0; i <= samples; ++i, theta += step, z += zStep) {
x = center.x + r * FastMath.cos(theta);
y = center.y - r * FastMath.sin(theta);
buf.put(x).put(y).put(z);
}
return buf;
}
private int lineNum;
private boolean clockwise;
private static int samples = 64;
}
Any help is appreciated