diff options
Diffstat (limited to 'src/com/mbien/opencl/demos/julia3d/UserSceneController.java')
-rw-r--r-- | src/com/mbien/opencl/demos/julia3d/UserSceneController.java | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/com/mbien/opencl/demos/julia3d/UserSceneController.java b/src/com/mbien/opencl/demos/julia3d/UserSceneController.java new file mode 100644 index 0000000..849de3a --- /dev/null +++ b/src/com/mbien/opencl/demos/julia3d/UserSceneController.java @@ -0,0 +1,249 @@ +package com.mbien.opencl.demos.julia3d; + +import com.mbien.opencl.demos.julia3d.structs.RenderingConfig; +import com.mbien.opencl.demos.julia3d.structs.Vec; +import java.awt.Component; +import java.awt.Point; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import static java.lang.Math.*; +import static com.mbien.opencl.demos.julia3d.Renderer.*; + +/** + * Utility class for interacting with a scene. Supports rotation and zoom around origin. + * @author Michael Bien + */ +public class UserSceneController { + + private Point dragstart; + private RenderingConfig model; + private Renderer view; + + private enum MOUSE_MODE { DRAG_ROTATE, DRAG_ZOOM } + private MOUSE_MODE dragmode = MOUSE_MODE.DRAG_ROTATE; + + + public void init(Renderer view, Component component, RenderingConfig model) { + initMouseListeners(component); + this.view = view; + this.model = model; + } + + private void initMouseListeners(Component component) { + + MouseAdapter mouseAdapter = new MouseAdapter() { + @Override + public void mouseDragged(MouseEvent e) { + + int x = e.getX(); + int y = e.getY(); + + switch (dragmode) { + case DRAG_ROTATE: + if (dragstart != null) { + int height = model.getHeight(); + int width = model.getWidth(); + + int ry = height - y - 1; + int baseMu1 = width - MU_RECT_SIZE - 2; + int baseMu2 = 1; + int baseMu3 = width - MU_RECT_SIZE - 2; + int baseMu4 = MU_RECT_SIZE + 2; + + if ((x >= baseMu1 && x <= baseMu1 + MU_RECT_SIZE) && (ry >= baseMu2 && ry <= baseMu2 + MU_RECT_SIZE)) { + float[] mu = model.getMu(); + mu[0] = 3.f * ( x - baseMu1) / (float)MU_RECT_SIZE - 1.5f; + mu[1] = 3.f * (ry - baseMu2) / (float)MU_RECT_SIZE - 1.5f; + model.setMu(mu); + } else if ((x >= baseMu3 && x <= baseMu3 + MU_RECT_SIZE) && (ry >= baseMu4 && ry <= baseMu4 + MU_RECT_SIZE)) { + float[] mu = model.getMu(); + mu[2] = 3.f * ( x - baseMu3) / (float)MU_RECT_SIZE - 1.5f; + mu[3] = 3.f * (ry - baseMu4) / (float)MU_RECT_SIZE - 1.5f; + model.setMu(mu); + } else { + rotateCameraYbyOrig(0.01f * (x - dragstart.getX())); + rotateCameraXbyOrig(0.01f * (y - dragstart.getY())); + } + } + dragstart = e.getPoint(); + view.update(); + break; + case DRAG_ZOOM: + if (dragstart != null) { + float zoom = (float) ((y - dragstart.getY()) / 10.0f); + zoom(zoom); + } + dragstart = e.getPoint(); + view.update(); + break; + } + + } + + @Override + public void mousePressed(MouseEvent e) { + switch (e.getButton()) { + case (MouseEvent.BUTTON1): + dragmode = MOUSE_MODE.DRAG_ROTATE; + break; + case (MouseEvent.BUTTON2): + dragmode = MOUSE_MODE.DRAG_ZOOM; + break; + case (MouseEvent.BUTTON3): + dragmode = MOUSE_MODE.DRAG_ZOOM; + break; + } + } + + @Override + public void mouseReleased(MouseEvent e) { + switch (e.getButton()) { + case (MouseEvent.BUTTON1): + dragmode = MOUSE_MODE.DRAG_ZOOM; + break; + case (MouseEvent.BUTTON2): + dragmode = MOUSE_MODE.DRAG_ROTATE; + break; + case (MouseEvent.BUTTON3): + dragmode = MOUSE_MODE.DRAG_ROTATE; + break; + } + + dragstart = null; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + float zoom = e.getWheelRotation() * 0.1f; + zoom(zoom); + view.update(); + } + + }; + + KeyAdapter keyAdapter = new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + + switch (e.getKeyChar()) { + case 'l': + model.setEnableShadow(model.getEnableShadow()==0 ? 1 : 0); + break; + case '1': + model.setEpsilon(model.getEpsilon() * 0.75f); + break; + case '2': + model.setEpsilon(model.getEpsilon() * 1.f / 0.75f); + break; + case '3': + model.setMaxIterations(max(1, model.getMaxIterations() -1)); + break; + case '4': + model.setMaxIterations(min(12, model.getMaxIterations()+1)); + break; + case '5': + model.setSuperSamplingSize(max(1, model.getSuperSamplingSize() -1)); + break; + case '6': + model.setSuperSamplingSize(min(5, model.getSuperSamplingSize() +1)); + break; + default: + break; + } + view.update(); + + } + + }; + + component.addKeyListener(keyAdapter); + + component.addMouseListener(mouseAdapter); + component.addMouseMotionListener(mouseAdapter); + component.addMouseWheelListener(mouseAdapter); + + } + private void zoom(float zoom) { + Vec orig = model.getCamera().getOrig(); + orig.setX(orig.getX()+zoom) + .setY(orig.getY()+zoom) + .setZ(orig.getZ()+zoom); + } + + private void rotateLightX(float k) { + float[] light = model.getLight(); + float y = light[1]; + float z = light[2]; + light[1] = (float) ( y * cos(k) + z * sin(k)); + light[2] = (float) (-y * sin(k) + z * cos(k)); + model.setLight(light); + } + + private void rotateLightY(float k) { + float[] light = model.getLight(); + float x = light[0]; + float z = light[2]; + light[0] = (float) (x * cos(k) - z * sin(k)); + light[2] = (float) (x * sin(k) + z * cos(k)); + model.setLight(light); + } + + private void rotateCameraXbyOrig(double k) { + Vec orig = model.getCamera().getOrig(); + float y = orig.getY(); + float z = orig.getZ(); + orig.setY((float) ( y * cos(k) + z * sin(k))); + orig.setZ((float) (-y * sin(k) + z * cos(k))); + } + + private void rotateCameraYbyOrig(double k) { + Vec orig = model.getCamera().getOrig(); + float x = orig.getX(); + float z = orig.getZ(); + orig.setX((float) (x * cos(k) - z * sin(k))); + orig.setZ((float) (x * sin(k) + z * cos(k))); + } + + + public final static void vadd(Vec v, Vec a, Vec b) { + v.setX(a.getX() + b.getX()); + v.setY(a.getY() + b.getY()); + v.setZ(a.getZ() + b.getZ()); + } + + public final static void vsub(Vec v, Vec a, Vec b) { + v.setX(a.getX() - b.getX()); + v.setY(a.getY() - b.getY()); + v.setZ(a.getZ() - b.getZ()); + } + + public final static void vmul(Vec v, float s, Vec b) { + v.setX(s * b.getX()); + v.setY(s * b.getY()); + v.setZ(s * b.getZ()); + } + + public final static float vdot(Vec a, Vec b) { + return a.getX() * b.getX() + + a.getY() * b.getY() + + a.getZ() * b.getZ(); + } + + public final static void vnorm(Vec v) { + float s = (float) (1.0f / sqrt(vdot(v, v))); + vmul(v, s, v); + } + + public final static void vxcross(Vec v, Vec a, Vec b) { + v.setX(a.getY() * b.getZ() - a.getZ() * b.getY()); + v.setY(a.getZ() * b.getX() - a.getX() * b.getZ()); + v.setZ(a.getX() * b.getY() - a.getY() * b.getX()); + } + + +}
\ No newline at end of file |