PtolemyPluginCreate: AxisPlugin.java

File AxisPlugin.java, 8.2 kB (added by antonio, 20 months ago)
Line 
1/**
2 * Ptolemy3D - a Java-based 3D Viewer for GeoWeb applications.
3 * Copyright (C) 2008 Mark W. Korver
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18package org.ptolemy3d.plugin;
19
20import com.sun.opengl.util.j2d.TextRenderer;
21import java.awt.Color;
22import java.awt.Font;
23import java.io.IOException;
24import javax.media.opengl.GL;
25import javax.media.opengl.glu.GLU;
26import org.ptolemy3d.Ptolemy3D;
27import org.ptolemy3d.Ptolemy3DConfiguration;
28import org.ptolemy3d.io.Communicator;
29import org.ptolemy3d.scene.Plugin;
30import org.ptolemy3d.view.Camera;
31
32/**
33 * Basic demonstration of plugin creating. Shows the cartesian axis used in
34 * ptolemy3D: RED - X, GREEN - Y, BLUE - Z.
35 *
36 * @author Antonio Santiago <asantiagop@gmail.com>
37 */
38public class AxisPlugin implements Plugin
39{
40
41    private static final String NAME = "AXIS_PLUGIN_";
42    private int index = -1;
43    private boolean status = true;
44    //
45    private Ptolemy3D ptolemy = null;
46    private GL gl = null;
47    private TextRenderer renderer = new TextRenderer(new Font(Font.SANS_SERIF, Font.BOLD, 14));
48    //
49    private boolean showLabels = false;
50
51    /**
52     * Initialize all non OpenGL datas. This is called just after the object instanciation.
53     * OpenGL Context is NOT current here, initialize all OpenGL related datas in <code>initGL</code>.
54     */
55    public void init(Ptolemy3D ptolemy)
56    {
57        this.ptolemy = ptolemy;
58    }
59
60    /**
61     * Notify the index of the plugin.
62     */
63    public void setPluginIndex(int index)
64    {
65        this.index = index;
66    }
67
68    /**
69     * Called a single time at initialisation.
70     */
71    public void setPluginParameters(String params)
72    {
73        String p[] = params.split(",");
74        if (p.length > 0)
75        {
76            showLabels = true;
77        }
78    }
79
80    /**
81     * Called when camera motion is stopped.
82     */
83    public void motionStop(GL gl)
84    {
85    }
86
87    /**
88     * Ray trace to find an intersection with the plugin geometry.
89     */
90    public boolean pick(double[] intersectPoint, double[][] ray)
91    {
92        return false;
93    }
94
95    /**
96     * Called when the landscape has been picked.
97     * @param intersectPoint picking intersection point.
98     */
99    public boolean onPick(double[] intersectPoint)
100    {
101        return false;
102    }
103
104    /**
105     * Call by the tile loader to let the plugin request data.
106     */
107    public void tileLoaderAction(Communicator com) throws IOException
108    {
109    }
110
111    /**
112     * Execute a plugin command.
113     *
114     * @param commandName command type
115     * @param commandParams command parameters
116     * @return if any value is returned, return it in a Stirng.
117     */
118    public String pluginAction(String commandname, String command_params)
119    {
120        if (commandname.equalsIgnoreCase("status"))
121        {
122            status = (Integer.parseInt(command_params) == 1) ? true : false;
123        }
124        else if (commandname.equalsIgnoreCase("getLayerName"))
125        {
126            return NAME + index;
127        }
128        return null;
129    }
130
131    /**
132     * Called when landscape status has been changed. Plugin must reload some data due to this change.
133     */
134    public void reloadData()
135    {
136    }
137
138    /**
139     * Initialize all OpenGL datas. OpenGL Context is current.
140     */
141    public void initGL(GL gl)
142    {
143    }
144
145    /**
146     * Render OpenGL geometry.
147     */
148    public void draw(GL gl)
149    {
150        if (!status)
151        {
152            return;
153        }
154
155        this.gl = gl;
156
157        double rad = Ptolemy3DConfiguration.EARTH_RADIUS * 1.1;
158        double x_axis[] =
159        {
160            rad, 0, 0
161        };
162        double y_axis[] =
163        {
164            0, rad, 0
165        };
166        double z_axis[] =
167        {
168            0, 0, rad
169        };
170
171        // Store attributes that will change
172        gl.glPushAttrib(
173                GL.GL_CURRENT_BIT |
174                GL.GL_ENABLE_BIT |
175                GL.GL_LINE_BIT);
176        gl.glDisable(GL.GL_TEXTURE_2D);
177
178        // Draw line axis
179        gl.glLineWidth(3f);
180        gl.glBegin(GL.GL_LINES);
181        gl.glColor3f(1.0f, 0f, 0f);
182        gl.glVertex3d(0, 0, 0);
183        gl.glVertex3dv(x_axis, 0);
184        gl.glColor3f(0f, 1.0f, 0f);
185        gl.glVertex3d(0, 0, 0);
186        gl.glVertex3dv(y_axis, 0);
187        gl.glColor3f(0f, 0f, 1.0f);
188        gl.glVertex3d(0, 0, 0);
189        gl.glVertex3dv(z_axis, 0);
190        gl.glEnd();
191
192        // Get screen coordinates
193        double x_scr[] = worldToScreen(x_axis);
194        double y_scr[] = worldToScreen(y_axis);
195        double z_scr[] = worldToScreen(z_axis);
196
197        // Render axis labels
198        if (showLabels)
199        {
200            // Check what points are visible before changing the matrices.
201            boolean x_visible = isCartesianPointInView(x_axis);
202            boolean y_visible = isCartesianPointInView(y_axis);
203            boolean z_visible = isCartesianPointInView(z_axis);
204
205            // Store previous matrices and set orthographic perspective
206            int viewport[] = new int[4];
207            gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
208
209            gl.glMatrixMode(GL.GL_PROJECTION);
210            gl.glPushMatrix();
211            gl.glLoadIdentity();
212            gl.glOrtho(0, viewport[2], 0, viewport[3], -1, 1);
213            gl.glMatrixMode(GL.GL_MODELVIEW);
214            gl.glPushMatrix();
215            gl.glLoadIdentity();
216
217            // Draw text
218            renderer.beginRendering(viewport[2], viewport[3]);
219            if (x_visible)
220            {
221                renderer.setColor(Color.RED);
222                renderer.draw("AXIS X", (int) x_scr[0], (int) x_scr[1]);
223            }
224            if (y_visible)
225            {
226                renderer.setColor(Color.GREEN);
227                renderer.draw("AXIS Y", (int) y_scr[0], (int) y_scr[1]);
228            }
229            if (z_visible)
230            {
231                renderer.setColor(Color.BLUE);
232                renderer.draw("AXIS Z", (int) z_scr[0], (int) z_scr[1]);
233            }
234            renderer.endRendering();
235
236            gl.glMatrixMode(GL.GL_MODELVIEW);
237            gl.glPopMatrix();
238            gl.glMatrixMode(GL.GL_PROJECTION);
239            gl.glPopMatrix();
240        }
241
242        // Restore attributes and matrices.
243        gl.glPopAttrib();
244    }
245
246    /**
247     * Checks if a point is the visible side of the globe.
248     * @param point
249     * @return
250     */
251    public boolean isCartesianPointInView(final double point[])
252    {
253        final Camera camera = Ptolemy3D.ptolemy.camera;
254
255        // View forward vector
256        double[] forward =
257        {
258            -camera.cameraMat.m[0][2], -camera.cameraMat.m[1][2], -camera.cameraMat.m[2][2]
259        };
260
261        // Angle between vector (front/back face test)
262        double dot = (forward[0] * point[0]) + (forward[1] * point[1]) + (forward[2] * point[2]);
263        if (dot <= 0)
264        {
265            return true;
266        }
267        else
268        {
269            return false;
270        }
271    }
272
273    /**
274     * Projects a cartesion point in the camera space and returns the pixel
275     * position in OpenGL coordinate space, that is, (0,0) at bottom-lect.
276     * @param cartesian
277     */
278    private double[] worldToScreen(double[] cartesian)
279    {
280        GLU glu = new GLU();
281        double model[] = new double[16];
282        double proj[] = new double[16];
283        int viewport[] = new int[4];
284
285        gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, model, 0);
286        gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, proj, 0);
287        gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
288
289        double screen[] = new double[4];
290        glu.gluProject(cartesian[0], cartesian[1], cartesian[2], model, 0, proj, 0, viewport, 0, screen, 0);
291
292        return screen;
293    }
294
295    /**
296     * Destroy all OpenGL Related Datas. OpenGL Context is current.
297     */
298    public void destroyGL(GL gl)
299    {
300    }
301}