]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/proconf/g3d/common/OrbitalCamera.java
git-svn-id: https://www.simantics.org/svn/simantics/3d/trunk@22280 ac1ea38d-2e2b...
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / proconf / g3d / common / OrbitalCamera.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
3  * All rights reserved. This program and the accompanying materials\r
4  * are made available under the terms of the Eclipse Public License v1.0\r
5  * which accompanies this distribution, and is available at\r
6  * http://www.eclipse.org/legal/epl-v10.html\r
7  *\r
8  * Contributors:\r
9  *     VTT Technical Research Centre of Finland - initial API and implementation\r
10  *******************************************************************************/\r
11 package org.simantics.proconf.g3d.common;\r
12 \r
13 import javax.vecmath.AxisAngle4d;\r
14 import javax.vecmath.Matrix3d;\r
15 import javax.vecmath.Vector3d;\r
16 \r
17 import org.simantics.proconf.g3d.base.VecmathJmeTools;\r
18 \r
19 import com.jme.renderer.Camera;\r
20 \r
21 \r
22 /**\r
23  * Orbital camera\r
24  * <p>\r
25  * Modified version of fi.vtt.proconf.webmon.graphics3d.utils.OrbitalCamera<br>\r
26  *  Using floats instead of double<br>\r
27  * </p>\r
28  * \r
29  * \r
30  * @author Marko Luukkainen\r
31  *\r
32  */\r
33 public class OrbitalCamera {\r
34     \r
35     private Vector3d up = new Vector3d(0.0,1.0,0.0);\r
36     private static Vector3d up2 = new Vector3d(0.0,0.0,-1.0);\r
37     private static double minDistance = 0.5;\r
38     private Vector3d target = new Vector3d();\r
39     private Vector3d cameraPos = new Vector3d(10.0,0.0,0.0);\r
40     \r
41     \r
42     public void translate(Vector3d v) {\r
43         target.add(v);\r
44         cameraPos.add(v);\r
45     }\r
46     \r
47     public void rotateAroundTarget(Vector3d axis, double angle) {\r
48         Vector3d temp = new Vector3d(cameraPos);\r
49         temp.sub(target);\r
50         Matrix3d rotation = new Matrix3d();\r
51         rotation.set(new AxisAngle4d(axis,angle));\r
52         rotation.transform(temp);\r
53         temp.add(target);\r
54         cameraPos.set(temp);      \r
55     }\r
56     \r
57     public Vector3d getUnNormalizedHeading() {\r
58         Vector3d heading = new Vector3d(target);\r
59         heading.sub(cameraPos);\r
60         return heading;\r
61     }\r
62     \r
63     public Vector3d getUnNormalizedRight() {\r
64         Vector3d heading = getUnNormalizedHeading();\r
65         Vector3d right = new Vector3d();\r
66         right.cross(heading,up);\r
67         if (right.lengthSquared() < 0.01)\r
68             right.cross(heading,up2);\r
69         return right;\r
70     }\r
71     \r
72     public double getDistanceToTarget() {\r
73         Vector3d t = new Vector3d(target);\r
74         t.sub(cameraPos);\r
75         return t.length();\r
76     }\r
77     \r
78     public void moveToTarget(double distance) {\r
79         Vector3d heading = getUnNormalizedHeading();\r
80         double length = heading.length();\r
81         if (length + distance < minDistance) {\r
82             // cannot move closer\r
83             return;\r
84         }\r
85         heading.scale(distance / length); //normalizing and scaling by distance\r
86         cameraPos.add(heading);\r
87     }\r
88     \r
89     public void moveScaledToTarget(double s) {\r
90         Vector3d heading = getUnNormalizedHeading();\r
91         double currentLength = heading.length();\r
92         double length = currentLength * (1.0 - s);// heading.length();\r
93         if (length < minDistance) {\r
94            s = -minDistance / currentLength + 1.0;\r
95         }\r
96         heading.scale(s);\r
97          //normalizing and scaling by distance\r
98         cameraPos.add(heading);\r
99     }\r
100     \r
101     public void rotateUp(double angle) {\r
102         Vector3d right = getUnNormalizedRight();\r
103         double length = right.length();\r
104         // TODO : better handling of singular cases\r
105         if (length > 0.01)\r
106             right.scale(1.0/length);\r
107         else \r
108             right.set(-1.0,0.0,0.0);\r
109         rotateAroundTarget(right,angle);\r
110     }\r
111     \r
112     public void rotateRight(double angle) {\r
113         rotateAroundTarget(up,angle);\r
114     }\r
115     \r
116     public void moveRight(double length) {\r
117         Vector3d right = getUnNormalizedRight();\r
118         right.normalize();\r
119         right.scale(length);\r
120         translate(right);\r
121     }\r
122     \r
123     public void moveUp(double length) {\r
124         Vector3d u = new Vector3d(up);\r
125         u.scale(length);\r
126         translate(u);\r
127     }\r
128     \r
129     public void moveFront(double length) {\r
130         Vector3d right = getUnNormalizedRight();\r
131         Vector3d front = new Vector3d();\r
132         front.cross(up,right);\r
133         front.normalize();\r
134         front.scale(length);\r
135         translate(front);\r
136     }\r
137     \r
138     public void updateCamera() {\r
139         Vector3d t = new Vector3d(cameraPos);\r
140         t.sub(target);\r
141         t.normalize();\r
142         cam.setLocation(VecmathJmeTools.get(cameraPos));\r
143         \r
144         if (Math.abs(t.dot(up)) > 0.99) {\r
145                 cam.lookAt(VecmathJmeTools.get(target), VecmathJmeTools.get(up2));      \r
146         } else {\r
147                 cam.lookAt(VecmathJmeTools.get(target), VecmathJmeTools.get(up));\r
148         }\r
149         cam.update();\r
150         cam.apply();\r
151         \r
152     }\r
153 \r
154     /**\r
155      * @return Returns the cameraPos.\r
156      */\r
157     public Vector3d getCameraPos() {\r
158         return cameraPos;\r
159     }\r
160 \r
161     /**\r
162      * @param cameraPos The cameraPos to set.\r
163      */\r
164     public void setCameraPos(Vector3d cameraPos) {\r
165         this.cameraPos = cameraPos;\r
166     }\r
167 \r
168     /**\r
169      * @return Returns the target.\r
170      */\r
171     public Vector3d getTarget() {\r
172         return target;\r
173     }\r
174 \r
175     /**\r
176      * @param target The target to set.\r
177      */\r
178     public void setTarget(Vector3d target) {\r
179         this.target = target;\r
180     }\r
181     \r
182     public void setCameraPosRelativeToTarget(Vector3d targetToCam) {\r
183         targetToCam.add(target);\r
184         setCameraPos(targetToCam);\r
185     }\r
186     \r
187     public void setUp(Vector3d v) {\r
188         up.set(v);\r
189     }\r
190     \r
191     public Vector3d getUp() {\r
192         return up;\r
193     }\r
194     \r
195     public void setDefaultUp() {\r
196         up.set(0.0,1.0,0.0);\r
197     }\r
198     \r
199     private Camera cam;\r
200     \r
201     public void setCamera(Camera cam) {\r
202         this.cam = cam;\r
203     }\r
204     \r
205 }\r