Skip to content

Commit bc61712

Browse files
committed
removed test mode with main stereo view; completed stereo view for second device
1 parent 97eaebe commit bc61712

File tree

6 files changed

+170
-191
lines changed

6 files changed

+170
-191
lines changed

src/main/java/org/openmolecules/fx/viewer3d/OneEyeView.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,27 @@ public void handle(long now) {
3131
};
3232
}
3333

34-
public void startViewing() {
34+
public void start() {
3535
mTimer.start();
3636
}
3737

38-
public void pause() {
38+
public void stop() {
3939
mTimer.stop();
4040
}
4141

4242
private void redraw() {
43-
mParams.setViewport(new Rectangle2D(0, 0, getFitWidth(), getFitHeight()));
43+
double QUALITY_FACTOR = 2;
44+
int width = (int)(QUALITY_FACTOR * getFitWidth());
45+
int height = (int)(QUALITY_FACTOR * getFitHeight());
46+
47+
mParams.setViewport(new Rectangle2D(0, 0, width, height));
4448
if (mImage == null
45-
|| mImage.getWidth() != getFitWidth() || mImage.getHeight() != getFitHeight()) {
49+
|| mImage.getWidth() != width
50+
|| mImage.getHeight() != height)
4651
mImage = mWorldRoot.snapshot(mParams, null);
47-
} else {
52+
else
4853
mWorldRoot.snapshot(mParams, mImage);
49-
}
54+
5055
setImage(mImage);
5156
}
5257
}

src/main/java/org/openmolecules/fx/viewer3d/V3DMouseHandler.java

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -68,46 +68,49 @@ public V3DMouseHandler(final V3DScene scene) {
6868
scene.setOnScroll(se -> {
6969
// we modify the wheel delta depending on how quickly the wheel is rotated
7070
double delta = -WHEEL_MIN_FACTOR * se.getDeltaY(); // delta is the smallest possible clip step
71-
long millis = System.currentTimeMillis();
72-
long delay = Math.max(1L, millis - mRecentWheelMillis);
73-
if (delay < WHEEL_DELAY_LIMIT)
74-
delta *= Math.pow(WHEEL_MAX_FACTOR, (1.0 - (double)delay / WHEEL_DELAY_LIMIT));
75-
mRecentWheelMillis = millis;
76-
if(mHighlightedMol!=null) {
77-
boolean actionPerformed=false;
78-
actionPerformed = mScene.getEditor().scrolledOnMolecule(mHighlightedMol, mHighlightedMol.getHighlightedShape(), delta);
79-
if(actionPerformed) {
80-
for (int type = 0; type<MoleculeSurfaceAlgorithm.SURFACE_TYPE.length; type++)
81-
mHighlightedMol.setSurfaceMode(type ,V3DMolecule.SurfaceMode.NONE);
82-
mHighlightedMol.fireCoordinatesChange();
83-
Platform.runLater(() -> {
71+
if (delta != 0) {
72+
long millis = System.currentTimeMillis();
73+
long delay = Math.max(1L, millis - mRecentWheelMillis);
74+
if (delay < WHEEL_DELAY_LIMIT)
75+
delta *= Math.pow(WHEEL_MAX_FACTOR, (1.0 - (double)delay / WHEEL_DELAY_LIMIT));
76+
mRecentWheelMillis = millis;
77+
if(mHighlightedMol!=null) {
78+
boolean actionPerformed =
79+
mScene.getEditor().scrolledOnMolecule(mHighlightedMol, mHighlightedMol.getHighlightedShape(), delta);
80+
if(actionPerformed) {
81+
for (int type = 0; type<MoleculeSurfaceAlgorithm.SURFACE_TYPE.length; type++)
82+
mHighlightedMol.setSurfaceMode(type ,V3DMolecule.SurfaceMode.NONE);
8483
mHighlightedMol.fireCoordinatesChange();
85-
V3DMoleculeUpdater mFXMolUpdater = new V3DMoleculeUpdater(mHighlightedMol);
86-
mFXMolUpdater.update();
87-
});
88-
return;
84+
Platform.runLater(() -> {
85+
mHighlightedMol.fireCoordinatesChange();
86+
V3DMoleculeUpdater mFXMolUpdater = new V3DMoleculeUpdater(mHighlightedMol);
87+
mFXMolUpdater.update();
88+
});
89+
return;
90+
}
8991
}
90-
}
91-
if (V3DPopupMenu.sUseMouseWheelForClipping || se.isShiftDown()) {
92-
if (se.isControlDown()) {
93-
delta *= getScreenToObjectFactor (mScene.getCamera().farClipProperty().getValue());
94-
moveFarClip(delta, false);
92+
if (V3DPopupMenu.sUseMouseWheelForClipping || se.isShiftDown()) {
93+
if (se.isControlDown()) {
94+
delta *= getScreenToObjectFactor (mScene.getCamera().farClipProperty().getValue());
95+
moveFarClip(delta, false);
96+
}
97+
else {
98+
delta *= getScreenToObjectFactor (mScene.getCamera().nearClipProperty().getValue());
99+
if (delta < 0)
100+
moveFarClip(moveNearClip(delta), true);
101+
else
102+
moveNearClip(moveFarClip(delta, true));
103+
}
95104
}
96105
else {
97-
delta *= getScreenToObjectFactor (mScene.getCamera().nearClipProperty().getValue());
98-
if (delta < 0)
99-
moveFarClip(moveNearClip(delta), true);
106+
if (mAffectedMol == null) {
107+
translateCameraZ(-delta);
108+
}// this does not change the world rotation center
100109
else
101-
moveNearClip(moveFarClip(delta, true));
110+
translateMolecule(mAffectedMol, 0, 0, delta);
102111
}
103112
}
104-
else {
105-
if (mAffectedMol == null) {
106-
translateCameraZ(-delta);
107-
}// this does not change the world rotation center
108-
else
109-
translateMolecule(mAffectedMol, 0, 0, delta);
110-
}
113+
se.consume();
111114
} );
112115
scene.setOnMousePressed(me -> {
113116
mSelectedNode = me.getPickResult().getIntersectedNode();
@@ -414,14 +417,14 @@ private void translateExclusionSphere(VolumeSphere eSphere, double dx, double dy
414417
}
415418

416419
private void translateCameraXY(double dx, double dy) {
417-
double f = getScreenToObjectFactor(mScene.getWorld().getTranslateZ());
420+
double f = Math.max(0.01, getScreenToObjectFactor(mScene.getMeanZ()));
418421
Camera camera = mScene.getCamera();
419422
camera.setTranslateX(camera.getTranslateX() + 2*f*dx);
420423
camera.setTranslateY(camera.getTranslateY() + 2*f*dy);
421424
}
422425

423426
private void translateCameraZ(double dz) {
424-
double f = getScreenToObjectFactor(mScene.getWorld().getTranslateZ());
427+
double f = Math.max(0.01, getScreenToObjectFactor(mScene.getMeanZ()));
425428
Camera camera = mScene.getCamera();
426429
camera.setTranslateZ(camera.getTranslateZ() + 2*f*dz);
427430
}

src/main/java/org/openmolecules/fx/viewer3d/V3DPopupMenu.java

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,17 @@
2626
import javafx.beans.property.SimpleBooleanProperty;
2727
import javafx.beans.value.ChangeListener;
2828
import javafx.beans.value.ObservableValue;
29-
import javafx.geometry.Bounds;
29+
import javafx.collections.ObservableList;
3030
import javafx.geometry.Insets;
31+
import javafx.geometry.Rectangle2D;
3132
import javafx.scene.Node;
3233
import javafx.scene.PerspectiveCamera;
3334
import javafx.scene.control.ButtonBar.ButtonData;
34-
import javafx.scene.control.Dialog;
35-
import javafx.scene.control.Label;
36-
import javafx.scene.control.Menu;
37-
import javafx.scene.control.MenuItem;
3835
import javafx.scene.control.*;
3936
import javafx.scene.layout.VBox;
4037
import javafx.stage.FileChooser;
4138
import javafx.stage.FileChooser.ExtensionFilter;
39+
import javafx.stage.Screen;
4240
import org.openmolecules.fx.sunflow.RayTraceDialog;
4341
import org.openmolecules.fx.sunflow.RayTraceOptions;
4442
import org.openmolecules.fx.surface.ClipSurfaceCutter;
@@ -49,7 +47,6 @@
4947
import org.openmolecules.render.MoleculeArchitect;
5048
import org.openmolecules.render.TorsionStrainVisualization;
5149

52-
import java.awt.*;
5350
import java.util.EnumSet;
5451
import java.util.Optional;
5552

@@ -66,10 +63,9 @@ public class V3DPopupMenu extends ContextMenu {
6663
private final V3DMolecule mMolecule;
6764
private final V3DScene mScene;
6865

69-
public V3DPopupMenu(V3DScene scene, V3DMolecule fxmol) {
70-
if (sPopupMenu != null && sPopupMenu.isShowing()) {
66+
public V3DPopupMenu(final V3DScene scene, final V3DMolecule fxmol) {
67+
if (sPopupMenu != null && sPopupMenu.isShowing())
7168
sPopupMenu.hide();
72-
}
7369

7470
sPopupMenu = this;
7571
mMolecule = fxmol;
@@ -225,28 +221,26 @@ public V3DPopupMenu(V3DScene scene, V3DMolecule fxmol) {
225221
MenuItem itemStereoView = null;
226222
if (V3DStereoPane.getFullScreenView() == null) {
227223
itemStereoView = new Menu("Show Stereo View");
228-
GraphicsDevice[] graphicsDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
229-
int deviceNo = 0;
230-
for (GraphicsDevice gd : graphicsDevices) {
231-
Bounds sceneBounds = scene.localToScreen(scene.getBoundsInLocal());
232-
Rectangle deviceRect = gd.getDefaultConfiguration().getBounds();
233-
String deviceString = "Screen "+(++deviceNo)+" ["+deviceRect.width+"x"+deviceRect.height+"]";
234-
boolean fullscreen = !deviceRect.contains(sceneBounds.getMinX(), sceneBounds.getMinY());
224+
ObservableList<Screen> screens = Screen.getScreens();
225+
for (int i=0; i<screens.size(); i++) {
226+
final Screen screen = screens.get(i);
227+
Rectangle2D bounds = screen.getBounds();
228+
String deviceString = "Screen "+i+" ["+Math.round(screen.getOutputScaleX()*bounds.getWidth())+"x"+Math.round(screen.getOutputScaleY()*bounds.getHeight())+"]";
235229
MenuItem itemSBS = new MenuItem("SBS - "+deviceString);
236-
itemSBS.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, gd, V3DStereoPane.MODE_SBS, fullscreen));
230+
itemSBS.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, screen, V3DStereoPane.MODE_SBS));
237231
MenuItem itemHSBS = new MenuItem("HSBS - "+deviceString);
238-
itemHSBS.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, gd, V3DStereoPane.MODE_HSBS, fullscreen));
232+
itemHSBS.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, screen, V3DStereoPane.MODE_HSBS));
239233
MenuItem itemOU = new MenuItem("OU - "+deviceString);
240-
itemOU.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, gd, V3DStereoPane.MODE_OU, fullscreen));
234+
itemOU.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, screen, V3DStereoPane.MODE_OU));
241235
MenuItem itemHOU = new MenuItem("HOU - "+deviceString);
242-
itemHOU.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, gd, V3DStereoPane.MODE_HOU, fullscreen));
236+
itemHOU.setOnAction(e -> V3DStereoPane.createFullScreenView(scene, screen, V3DStereoPane.MODE_HOU));
243237

244238
((Menu)itemStereoView).getItems().addAll(itemSBS, itemHSBS, itemOU, itemHOU);
245239
}
246240
}
247241
else {
248242
itemStereoView = new MenuItem("Close Stereo View");
249-
itemStereoView.setOnAction(e -> V3DStereoPane.closeFullSCreenView() );
243+
itemStereoView.setOnAction(e -> V3DStereoPane.closeFullScreenView() );
250244
}
251245

252246
Menu menuView = new Menu("View");

src/main/java/org/openmolecules/fx/viewer3d/V3DScene.java

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ public class V3DScene extends SubScene implements LabelDeletionListener {
8282
protected static final double CAMERA_NEAR_CLIP = 1.0;
8383
protected static final double CAMERA_FAR_CLIP = 1000.0;
8484
protected static final double CAMERA_MIN_CLIP_THICKNESS = 2.0;
85-
private static final double EYE_DISTANCE = 0.5;
8685
private static final double CLIP_ATOM_PADDING = 3.0;
8786

8887
public enum MEASUREMENT { NONE(0), DISTANCE(2), ANGLE(3), TORSION(4);
@@ -127,7 +126,7 @@ public V3DScene(Group root, double width, double height, EnumSet<V3DScene.Viewer
127126

128127
setFill(Color.BLACK);
129128
buildLight();
130-
buildCamera(MODE_NONE);
129+
buildMainCamera();
131130
mMeasurements = new ArrayList<V3DMeasurement>();
132131
new V3DMouseHandler(this);
133132
new V3DKeyHandler(this);
@@ -459,6 +458,26 @@ public double[] getVisibleZRange() {
459458
return zr;
460459
}
461460

461+
public double getMeanZ() {
462+
double meanZ = 0;
463+
int count = 0;
464+
465+
for(V3DRotatableGroup fxmol : mWorld.getAllAttachedRotatableGroups()) {
466+
if (fxmol.isVisible()) {
467+
for (Node node:fxmol.getChildren()) {
468+
NodeDetail detail = (NodeDetail)node.getUserData();
469+
if (detail != null && detail.isAtom()) {
470+
Point3D p = node.localToScene(0.0, 0.0, 0.0);
471+
meanZ += p.getZ();
472+
count++;
473+
}
474+
}
475+
}
476+
}
477+
478+
return meanZ / count;
479+
}
480+
462481
public Point3D getCOGInGroup(V3DRotatableGroup group) {
463482
int count = 0;
464483
double x = 0.0;
@@ -666,43 +685,35 @@ private void buildLight() {
666685
mRoot.getChildren().addAll(lightGroup);
667686
}
668687

669-
private void buildCamera(int stereoMode) {
688+
private void buildMainCamera() {
670689
PerspectiveCamera camera = new PerspectiveCamera(true);
671690
camera.setNearClip(CAMERA_NEAR_CLIP);
672691
camera.setFarClip(CAMERA_FAR_CLIP);
673692
camera.setTranslateZ(-CAMERA_INITIAL_DISTANCE);
674-
if (stereoMode == MODE_SBS
675-
|| stereoMode == MODE_OU) {
676-
camera.setTranslateX(-EYE_DISTANCE/2);
677-
}
678-
else if (stereoMode == MODE_HSBS) {
679-
camera.setScaleX(2.0);
680-
camera.setTranslateX(-EYE_DISTANCE/2);
681-
}
682-
else if (stereoMode == MODE_HOU) {
683-
camera.setScaleY(2.0);
684-
camera.setTranslateX(-EYE_DISTANCE/2);
685-
}
686693
setCamera(camera);
687694
mRoot.getChildren().add(camera);
688695
}
689696

690-
public OneEyeView buildOneEyeView(boolean isRightEye, int stereoMode) {
691-
PerspectiveCamera camera = new PerspectiveCamera(true);
692-
camera.setNearClip(CAMERA_NEAR_CLIP);
693-
camera.setFarClip(CAMERA_FAR_CLIP);
694-
camera.setTranslateZ(-CAMERA_INITIAL_DISTANCE);
697+
public OneEyeView buildOneEyeView(final double eyeShift, int stereoMode) {
698+
final PerspectiveCamera camera = new PerspectiveCamera(true);
695699
if (stereoMode == MODE_HSBS) {
696700
camera.setScaleX(2.0);
697701
}
698702
else if (stereoMode == MODE_HOU) {
699703
camera.setScaleX(0.5);
700704
}
701-
camera.setTranslateX(isRightEye ? EYE_DISTANCE/2 : -EYE_DISTANCE/2);
702705

703-
getCamera().translateXProperty().addListener((observableValue, number, t1) -> camera.setTranslateX(getCamera().getTranslateX() + EYE_DISTANCE));
706+
camera.setTranslateX(getCamera().getTranslateX() + eyeShift);
707+
camera.setTranslateY(getCamera().getTranslateY());
708+
camera.setTranslateZ(getCamera().getTranslateZ());
709+
camera.setNearClip(getCamera().getNearClip());
710+
camera.setFarClip(getCamera().getFarClip());
711+
712+
getCamera().translateXProperty().addListener((observableValue, number, t1) -> camera.setTranslateX(getCamera().getTranslateX() + eyeShift));
704713
getCamera().translateYProperty().addListener((observableValue, number, t1) -> camera.setTranslateY(getCamera().getTranslateY()));
705714
getCamera().translateZProperty().addListener((observableValue, number, t1) -> camera.setTranslateZ(getCamera().getTranslateZ()));
715+
getCamera().nearClipProperty().addListener((observableValue, number, t1) -> camera.setNearClip(getCamera().getNearClip()));
716+
getCamera().farClipProperty().addListener((observableValue, number, t1) -> camera.setFarClip(getCamera().getFarClip()));
706717

707718
return new OneEyeView(this, camera);
708719
}

0 commit comments

Comments
 (0)