diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/.classpath b/org.fortiss.tooling.graphicsGL.ui/trunk/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..afc0beec366ce4209038e29fa13136254a26e248 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/.classpath @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="test-src"/> + <classpathentry exported="true" kind="lib" path="lib/slick-util.jar"/> + <classpathentry kind="output" path="build"/> +</classpath> diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/.project b/org.fortiss.tooling.graphicsGL.ui/trunk/.project new file mode 100644 index 0000000000000000000000000000000000000000..b792e83d14014022dee74a73b5f3013ed8568353 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.fortiss.tooling.graphics3D.ui</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/META-INF/MANIFEST.MF b/org.fortiss.tooling.graphicsGL.ui/trunk/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..3b27e1df7dd9b3b609f5927cfed1cfb869a11774 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/META-INF/MANIFEST.MF @@ -0,0 +1,30 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Fortiss Tooling Graphics 3D UI +Bundle-SymbolicName: org.fortiss.tooling.graphics3D.ui;singleton:=true +Bundle-Version: 2.1.0.qualifier +Bundle-Activator: org.fortiss.tooling.graphics3D.ui.ToolingGraphics3DUIActivator +Require-Bundle: org.fortiss.tooling.graphics3D;bundle-version="2.1.0";visibility:=reexport, + org.fortiss.tooling.base.ui;bundle-version="2.1.0";visibility:=reexport, + org.lwjgl;bundle-version="2.8.4";visibility:=reexport, + org.fortiss.af3.expression.ui;bundle-version="2.1.0" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-Vendor: fortiss GmbH +Export-Package: org.fortiss.tooling.graphics3D.ui, + org.fortiss.tooling.graphics3D.ui.camera, + org.fortiss.tooling.graphics3D.ui.draw, + org.fortiss.tooling.graphics3D.ui.editor, + org.fortiss.tooling.graphics3D.ui.light, + org.fortiss.tooling.graphics3D.ui.objects, + org.fortiss.tooling.graphics3D.ui.picker, + org.fortiss.tooling.graphics3D.ui.util, + org.newdawn.slick, + org.newdawn.slick.loading, + org.newdawn.slick.openal, + org.newdawn.slick.opengl, + org.newdawn.slick.opengl.renderer, + org.newdawn.slick.tests, + org.newdawn.slick.util +Bundle-ClassPath: lib/slick-util.jar, + . diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/build.properties b/org.fortiss.tooling.graphicsGL.ui/trunk/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..77336488359293d11b1b19806ea1fe9ebc445744 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/build.properties @@ -0,0 +1,12 @@ +# <copyright> +# </copyright> +# +# $Id$ + +bin.includes = .,\ + META-INF/,\ + plugin.xml,\ + lib/slick-util.jar +source.. = src/,\ + test-src/ +output.. = build/ diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/lib/slick-util.jar b/org.fortiss.tooling.graphicsGL.ui/trunk/lib/slick-util.jar new file mode 100644 index 0000000000000000000000000000000000000000..9e20b22adf3522640ff9bf79956c2258720c90e2 Binary files /dev/null and b/org.fortiss.tooling.graphicsGL.ui/trunk/lib/slick-util.jar differ diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/plugin.xml b/org.fortiss.tooling.graphicsGL.ui/trunk/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..269753fc3720ffa4867ec32c8bc0e89fc302cfb5 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/plugin.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> + +<!-- + <copyright> + </copyright> + + $Id$ +--> +<plugin> + <extension + point="org.fortiss.tooling.kernel.ui.modelEditorBinding"> + <modelEditorBinding + binding="test.org.fortiss.tooling.graphics3D.ui.Test3DEditorBinding"> + <modelElementClass + modelElementClass="org.fortiss.af3.expression.model.DataDictionary"> + </modelElementClass> + </modelEditorBinding> + </extension> + +</plugin> diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/ToolingGraphics3DUIActivator.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/ToolingGraphics3DUIActivator.java new file mode 100644 index 0000000000000000000000000000000000000000..d7fa0698159a64ccdf042f1850611e0ff38d743f --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/ToolingGraphics3DUIActivator.java @@ -0,0 +1,64 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: E9B79759E2C0C013BE2B19DE87749838 + */ +public class ToolingGraphics3DUIActivator extends AbstractUIPlugin { + + /** The plug-in ID. */ + public static final String PLUGIN_ID = ToolingGraphics3DUIActivator.class.getPackage() + .getName(); //$NON-NLS-1$ + + /** The shared instance. */ + private static ToolingGraphics3DUIActivator plugin; + + /** {@inheritDoc} */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /** {@inheritDoc} */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** Returns the shared instance. */ + public static ToolingGraphics3DUIActivator getDefault() { + return plugin; + } + + /** Returns the image descriptor for the given icon file. */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/camera/Camera.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/camera/Camera.java new file mode 100644 index 0000000000000000000000000000000000000000..bf05dbb816fb646e14e8da78f24f625dca8a7f1f --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/camera/Camera.java @@ -0,0 +1,75 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.camera; + +import static org.lwjgl.util.glu.GLU.gluLookAt; + +import org.lwjgl.util.vector.Vector3f; + +/** + * Class representing the camera with the Z axis as up vector. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 6DFDC1792DF675AF5ED360810E3635D7 + */ +public class Camera { + + /** The camera position. */ + protected Vector3f pos = new Vector3f(10.0f, 10.0f, 10.0f); + + /** The camera target. */ + private Vector3f target = new Vector3f(); + + /** Constructor. */ + public Camera() { + } + + /** Sets the camera position. */ + public void setPosition(float cx, float cy, float cz) { + pos = new Vector3f(cx, cy, cz); + } + + /** Alters the camera position with the given deltas. */ + public void alterPosition(float dx, float dy, float dz) { + setPosition(pos.x + dx, pos.y + dy, pos.z + dz); + } + + /** Sets the camera target. */ + public void setTarget(float tx, float ty, float tz) { + target = new Vector3f(tx, ty, tz); + } + + /** Alters the camera target with the given deltas. */ + public void alterTarget(float dx, float dy, float dz) { + target.x = target.x + dx; + target.y = target.y + dy; + target.z = target.z + dz; + } + + /** Applies the camera position and view target to GL before rendering starts. */ + public void applyForRendering() { + gluLookAt(pos.x, pos.y, pos.z, target.x, target.y, target.z, 0, 0, 1.0f); + } + + /** Applies the camera position and view target to GL before picking starts. */ + public void applyForPicking() { + gluLookAt(pos.x, pos.y, pos.z, target.x, target.y, target.z, 0, 0, 1.0f); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/camera/MovingCameraWithPitchAndYaw.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/camera/MovingCameraWithPitchAndYaw.java new file mode 100644 index 0000000000000000000000000000000000000000..852cba96d2293baee05e6f62044e1fb50b6cb257 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/camera/MovingCameraWithPitchAndYaw.java @@ -0,0 +1,121 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.camera; + +import static java.lang.Math.cos; +import static java.lang.Math.sin; +import static java.lang.Math.toRadians; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.X_UNIT_VECTOR; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.Z_UNIT_VECTOR; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.rotate; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.translate; +import static org.lwjgl.util.glu.GLU.gluLookAt; + +/** + * A {@link Camera} which can be configured with pitch and yaw angle. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 8D71137B475BD3A8ECD299C288D95E15 + */ +public class MovingCameraWithPitchAndYaw extends Camera { + + /** The yaw angle. */ + private float yawAngle = 0.0f; + + /** The pitch angle. */ + private float pitchAngle = 0.0f; + + /** Alter the pitch angle. */ + public void pitch(float amount) { + pitchAngle += amount; + if(pitchAngle >= 85.0f) { + pitchAngle = 85.0f; + } else if(pitchAngle <= -85.0) { + pitchAngle = -85.0f; + } + } + + /** Alter the yaw angle. */ + public void yaw(float amount) { + yawAngle += amount; + } + + /** Move forward for the given distance. */ + public void forward(float distance) { + float dx = distance * (float)sin(toRadians(yawAngle)); + float dy = distance * (float)cos(toRadians(yawAngle)); + super.alterPosition(dx, dy, 0); + } + + /** Move backward for the given distance. */ + public void backward(float distance) { + forward(-distance); + } + + /** Move left for the given distance. */ + public void left(float distance) { + float dx = distance * (float)sin(toRadians(yawAngle - 90)); + float dy = distance * (float)cos(toRadians(yawAngle - 90)); + super.alterPosition(dx, dy, 0); + } + + /** Move right for the given distance. */ + public void right(float distance) { + left(-distance); + } + + /** Move up for the given distance. */ + public void up(float distance) { + super.alterPosition(0, 0, distance); + } + + /** Move down for the given distance. */ + public void down(float distance) { + up(-distance); + } + + /** {@inheritDoc} */ + @Override + public void applyForRendering() { + // from origin look at Y axis + gluLookAt(0, 0, 0, 0, 1.0f, 0, 0, 0, 1.0f); + rotate(pitchAngle, X_UNIT_VECTOR); + rotate(yawAngle, Z_UNIT_VECTOR); + translate(-pos.x, -pos.y, -pos.z); + } + + /** {@inheritDoc} */ + @Override + public void applyForPicking() { + applyForRendering(); + } + + /** {@inheritDoc} */ + @Override + public void setTarget(float tx, float ty, float tz) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public void alterTarget(float dx, float dy, float dz) { + throw new UnsupportedOperationException(); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/draw/Lwjgl3DCanvas.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/draw/Lwjgl3DCanvas.java new file mode 100644 index 0000000000000000000000000000000000000000..118f54736c96f5f0e765664512235639688c5c51 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/draw/Lwjgl3DCanvas.java @@ -0,0 +1,103 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.draw; + +import static org.fortiss.tooling.graphics3D.ui.ToolingGraphics3DUIActivator.getDefault; +import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; +import static org.lwjgl.opengl.GL11.GL_MODELVIEW; +import static org.lwjgl.opengl.GL11.GL_PROJECTION; +import static org.lwjgl.opengl.GL11.glLoadIdentity; +import static org.lwjgl.opengl.GL11.glMatrixMode; +import static org.lwjgl.opengl.GL11.glViewport; +import static org.lwjgl.opengl.GLContext.useContext; +import static org.lwjgl.util.glu.GLU.gluPerspective; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.opengl.GLCanvas; +import org.eclipse.swt.opengl.GLData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Listener; +import org.lwjgl.LWJGLException; + +/** + * Canvas for drawing LWJGL content onto a SWT widget. It uses double buffer, dpeth buffer and four + * sample buffers. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 83ECFD2B231D8EC0A50D3D363571A870 + */ +public class Lwjgl3DCanvas extends GLCanvas { + + /** Constructor. */ + public Lwjgl3DCanvas(Composite parent, GLData data) { + super(parent, SWT.NONE, data); + } + + /** Constructor. */ + public Lwjgl3DCanvas(Composite parent) { + this(parent, createDefaultGLData()); + } + + /** Creates the default {@link GLData}. */ + private static GLData createDefaultGLData() { + GLData data = new GLData(); + // use double buffering + data.doubleBuffer = true; + // allow depth buffering + data.depthSize = 1; + // enable four sample buffers for anti-aliasing + data.sampleBuffers = 1; + data.samples = 4; + return data; + } + + /** Adds the given listener to handle the canvas resize events. */ + public void addResizeHandler(Listener handler) { + addListener(SWT.Resize, handler); + } + + /** Sets this canvas as the current canvas and tells OGL to use it. */ + public void setCurrentAndUseContext() { + try { + setCurrent(); + useContext(this); + } catch(LWJGLException ex) { + error(getDefault(), ex.getMessage(), ex); + } + } + + /** Sets the view port and perspective projection matrix. */ + public void setViewportAndPerspective(int width, int height, float fieldOfViewAngle, + float nearDistance, float farDistance) { + if(nearDistance <= 0 || farDistance <= 0) { + throw new IllegalArgumentException("Z distances of perspective must be greater 0."); + } + float aspect = (float)width / (float)height; + setCurrentAndUseContext(); + // set viewport and alter set projection matrix + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(fieldOfViewAngle, aspect, nearDistance, farDistance); + // return GL state to model matrix + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/draw/Lwjgl3DRenderThread.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/draw/Lwjgl3DRenderThread.java new file mode 100644 index 0000000000000000000000000000000000000000..99779213eb999b9eb5848f925b1f96f74b600d02 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/draw/Lwjgl3DRenderThread.java @@ -0,0 +1,86 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.draw; + +import static org.eclipse.ui.PlatformUI.getWorkbench; + +/** + * Thread class for the render thread with a default sleep period of 40ms (i.e. about 25fps). + * The thread executes a refresh of the canvas using a Display async execution and dies as soon as + * the canvas is disposed. Note that the refresh is only performed if the canvas is not disposed and + * is visible. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 6CD38411345BE68238AF29F9A98D9CC5 + */ +public class Lwjgl3DRenderThread extends Thread { + + /** The GLCanvas to be rendered by this thread. */ + private final Lwjgl3DCanvas canvas; + + /** The render thread sleep period. */ + private int sleepPeriod = 40; + + /** The content renderer runnable. */ + private final Runnable contentRenderer; + + /** Constructor. */ + public Lwjgl3DRenderThread(Lwjgl3DCanvas canvas, Runnable contentRenderer) { + if(canvas == null) { + throw new IllegalArgumentException("Canvas may not be null."); + } + if(contentRenderer == null) { + throw new IllegalArgumentException("Content render may not be null."); + } + this.canvas = canvas; + this.contentRenderer = contentRenderer; + } + + /** Sets the sleep period of the render thread in milliseconds. */ + public void setSleepPeriod(int sleepPeriod) { + this.sleepPeriod = sleepPeriod; + } + + /** {@inheritDoc} */ + @Override + public void run() { + try { + sleep(sleepPeriod); + while(!canvas.isDisposed()) { + getWorkbench().getDisplay().asyncExec(refresher); + sleep(sleepPeriod); + } + } catch(InterruptedException e) { + e.printStackTrace(); + } + } + + /** The refresher display runner. */ + private Runnable refresher = new Runnable() { + @Override + public void run() { + if(!canvas.isDisposed() && canvas.isVisible()) { + canvas.setCurrentAndUseContext(); + contentRenderer.run(); + canvas.swapBuffers(); + } + } + }; +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/editor/EditorStatusBarItem.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/editor/EditorStatusBarItem.java new file mode 100644 index 0000000000000000000000000000000000000000..9eb05e32e792b62e5ab926ddddc01a0dca2e7c0b --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/editor/EditorStatusBarItem.java @@ -0,0 +1,59 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.editor; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.StatusLineLayoutData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * Status bar for the {@link Graphical3DEditorBase}. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 3CBE8094441E5D8E420FC65504AFEE20 + */ +public class EditorStatusBarItem extends ContributionItem { + + /** The status bar label. */ + private CLabel label; + + /** {@inheritDoc} */ + @Override + public void fill(Composite i_parent) { + Label sep = new Label(i_parent, SWT.SEPARATOR); + label = new CLabel(i_parent, SWT.SHADOW_NONE); + + StatusLineLayoutData data = new StatusLineLayoutData(); + data.widthHint = 400; + label.setLayoutData(data); + + data = new StatusLineLayoutData(); + data.heightHint = 32; + sep.setLayoutData(data); + } + + /** Sets the status line text. */ + public void setText(String text) { + label.setText(text); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/editor/Graphical3DEditorBase.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/editor/Graphical3DEditorBase.java new file mode 100644 index 0000000000000000000000000000000000000000..7a554efd98cac7c1fd75628f82d958f74e66684d --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/editor/Graphical3DEditorBase.java @@ -0,0 +1,264 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.editor; + +import static org.fortiss.tooling.graphics3D.ui.ToolingGraphics3DUIActivator.getDefault; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.clearCanvasAndLoadIdentity; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.initializeGL; +import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; +import static org.newdawn.slick.Color.black; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.fortiss.tooling.graphics3D.ui.camera.Camera; +import org.fortiss.tooling.graphics3D.ui.draw.Lwjgl3DCanvas; +import org.fortiss.tooling.graphics3D.ui.draw.Lwjgl3DRenderThread; +import org.fortiss.tooling.graphics3D.ui.objects.ViewObjectBase; +import org.fortiss.tooling.graphics3D.ui.picker.ModelObjectPicker; +import org.fortiss.tooling.kernel.ui.extension.base.EditorBase; +import org.lwjgl.LWJGLException; +import org.lwjgl.util.vector.Vector3f; + +/** + * Base class for 3D graphics editors. Sub-classes must provide a {@link Camera} and a + * {@link ViewObjectBase}, which are used to render the editor content. Sub-classes may react on + * mouse and key events by overriding the respective methods. + * <P> + * The rendering process is started by calling {@link #beginRenderLoop()}, which allows sub-classes + * to apply additional GL setup commands. Sub-classes maya change the perspective by overriding + * {@link #getPerspective()} and return a vector with the field of view, Z near distance, and Z far + * distance. Note that all three must be greater zero. + * <P> + * After the rendering is done the picking process starts if both {@link #pickX} and {@link #pickY} + * are greater or equal to zero and smaller than the widget width and height, respectively. + * Sub-classes should update these variables when they want to pick an object from the scene. The + * {@link #pickTargetChanged()} method is called whenever the picked object changes. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 908A7E484514F2EC6D3126014A55B7E9 + */ +public abstract class Graphical3DEditorBase<T extends EObject> extends EditorBase<T> implements + MouseListener, MouseTrackListener, MouseMoveListener, MouseWheelListener, KeyListener, + Listener { + + /** The 3D canvas. */ + protected Lwjgl3DCanvas canvas; + + /** The status line for simple text feedback. */ + protected EditorStatusBarItem statusBarItem; + + /** The render thread. */ + private Lwjgl3DRenderThread renderThread; + + /** The object picker. */ + private ModelObjectPicker picker = new ModelObjectPicker(); + + /** The current X position to be used during picking. */ + protected int pickX = -1; + + /** The current Y position to be used during picking. */ + protected int pickY = -1; + + /** The current picked object or {@code null} if no pickable object is at the picking location. */ + protected Object pickTarget; + + /** {@inheritDoc} */ + @Override + public final void handleEvent(Event event) { + Rectangle b = canvas.getBounds(); + Vector3f p = getPerspective(); + canvas.setViewportAndPerspective(b.width, b.height, p.x, p.y, p.z); + } + + /** Callback from render thread. */ + private Runnable renderCallback = new Runnable() { + @Override + public void run() { + try { + performRendering(); + performPicking(); + } catch(LWJGLException ex) { + error(getDefault(), ex.getMessage(), ex); + } + } + }; + + /** + * Called when the render loop starts, but after the camera was applied for rendering. + * Sub-classes should make GL calls to setup rendering. The default does nothing. + */ + @SuppressWarnings("unused") + protected void beginRenderLoop() throws LWJGLException { + // do nothing + } + + /** Returns the current camera to be used. */ + protected abstract Camera getCamera(); + + /** + * Sub-classes should provide the scene object here. The model object will be used for rendering + * and picking using {@link ViewObjectBase}'s respective methods. + */ + protected abstract ViewObjectBase getSceneModelObject(); + + /** Notification about the change of the pick target. The default does nothing. */ + protected void pickTargetChanged() { + // do nothing + } + + /** + * Returns the perspective projection (field of view, near distance, far distance). The default + * uses {@code 45.0f, 0.5f, 400.0f}. + */ + protected Vector3f getPerspective() { + return new Vector3f(45.0f, 0.5f, 400.0f); + } + + /** Performs the object picking operation. */ + private void performPicking() { + // avoid unnecessary picking if mouse is outside the canvas + if(pickX < 0 || pickX > canvas.getBounds().width || pickY < 0 || + pickY > canvas.getBounds().height) { + return; + } + Object p = picker.pickModelObject(pickX, pickY, getPerspective(), getSceneModelObject()); + if(pickTarget != p) { + pickTarget = p; + pickTargetChanged(); + } + } + + /** Performs the object rendering operation. */ + private void performRendering() throws LWJGLException { + clearCanvasAndLoadIdentity(black); + getCamera().applyForRendering(); + beginRenderLoop(); + getSceneModelObject().renderObject(); + } + + /** {@inheritDoc} */ + @Override + public void createPartControl(Composite parent) { + IStatusLineManager statusLine = getEditorSite().getActionBars().getStatusLineManager(); + statusBarItem = new EditorStatusBarItem(); + statusLine.add(statusBarItem); + + Composite c = new Composite(parent, SWT.NONE); + c.setLayout(new FillLayout()); + + canvas = new Lwjgl3DCanvas(c); + canvas.addResizeHandler(this); + canvas.addMouseListener(this); + canvas.addMouseMoveListener(this); + canvas.addMouseTrackListener(this); + canvas.addMouseWheelListener(this); + canvas.addKeyListener(this); + + canvas.setCurrentAndUseContext(); + initializeGL(); + + renderThread = new Lwjgl3DRenderThread(canvas, renderCallback); + renderThread.start(); + } + + /** {@inheritDoc} */ + @Override + public void setFocus() { + canvas.setFocus(); + } + + /** {@inheritDoc} */ + @Override + public void mouseDoubleClick(MouseEvent e) { + // ignore + } + + /** {@inheritDoc} */ + @Override + public void mouseDown(MouseEvent e) { + // ignore + } + + /** {@inheritDoc} */ + @Override + public void mouseUp(MouseEvent e) { + // ignore + } + + /** {@inheritDoc} */ + @Override + public void mouseEnter(MouseEvent e) { + // ignore + } + + /** + * {@inheritDoc} + * <P> + * Resets the picking position to (-1, -1). + */ + @Override + public void mouseExit(MouseEvent e) { + pickX = -1; + pickY = -1; + } + + /** {@inheritDoc} */ + @Override + public void mouseHover(MouseEvent e) { + // ignore + } + + /** {@inheritDoc} */ + @Override + public void mouseMove(MouseEvent e) { + // ignore + } + + /** {@inheritDoc} */ + @Override + public void mouseScrolled(MouseEvent e) { + // ignore + } + + /** {@inheritDoc} */ + @Override + public void keyPressed(KeyEvent e) { + // ignore + } + + /** {@inheritDoc} */ + @Override + public void keyReleased(KeyEvent e) { + // ignore + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/light/Light.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/light/Light.java new file mode 100644 index 0000000000000000000000000000000000000000..f8155d2c941c42746b81915e3b90e84a8a9eee06 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/light/Light.java @@ -0,0 +1,96 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.light; + +import static org.fortiss.tooling.graphics3D.ui.util.FloatBufferUtils.toFloatBuffer; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.color; +import static org.lwjgl.opengl.GL11.GL_DIFFUSE; +import static org.lwjgl.opengl.GL11.GL_LIGHT0; +import static org.lwjgl.opengl.GL11.GL_POSITION; +import static org.lwjgl.opengl.GL11.GL_SPECULAR; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glLight; + +import java.nio.FloatBuffer; + +import org.fortiss.tooling.graphics3D.model.Color3D; + +/** + * Class representing a light source. It is initialized with a GL light number (GL_LIGHT0, ..., + * GL_LIGHT7) and a {@link Color3D}, which determines the light color for ambient and diffuse. + * Specular light is set to white. The default position is (10,10,10). + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: E66B9A1E36BB0871D1F6B8C171070154 + */ +public class Light { + + /** The GL_LIGHTx to be used. */ + private final int glLightNumber; + + /** Constructor. */ + public Light(int glLight, Color3D color) { + glLightNumber = glLight; + setLightColor(color); + setPosition(10.0f, 10.0f, 10.0f); + } + + /** Constructor using GL_LIGHT0 and white light color. */ + public Light() { + this(GL_LIGHT0, color(1.0f, 1.0f, 1.0f)); + } + + /** Constructor using GL_LIGHT0 and the given light color. */ + public Light(Color3D color) { + this(GL_LIGHT0, color); + } + + /** Sets the light color. */ + public final void setLightColor(Color3D color) { + diffuseColor = toFloatBuffer(color.getRed(), color.getGreen(), color.getBlue(), 1.0f); + specularColor = toFloatBuffer(1.0f, 1.0f, 1.0f, 1.0f); + } + + /** The position. */ + private FloatBuffer lightPosition; + /** The diffuse color. */ + private FloatBuffer diffuseColor; + /** The specular color. */ + private FloatBuffer specularColor; + + /** Enables the light in GL. */ + public void enableLight() { + glEnable(glLightNumber); + glLight(glLightNumber, GL_POSITION, lightPosition); + glLight(glLightNumber, GL_DIFFUSE, diffuseColor); + glLight(glLightNumber, GL_SPECULAR, specularColor); + } + + /** Disables the light in GL. */ + public void disableLight() { + glDisable(glLightNumber); + } + + /** Sets the light position. */ + public void setPosition(float x, float y, float z) { + lightPosition = toFloatBuffer(new float[] {x, y, z, 1.0f}); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/light/Light3DLight.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/light/Light3DLight.java new file mode 100644 index 0000000000000000000000000000000000000000..0d15cb3673052fc02b8e2768fe54bb9195ddc1f4 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/light/Light3DLight.java @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.light; + +import static org.lwjgl.opengl.GL11.glDisable; + +import org.fortiss.tooling.graphics3D.model.scene.Light3D; +import org.fortiss.tooling.graphics3D.ui.util.GLPrimitives; + +/** + * Class representing a light source based on the model object of class {@link Light3D}. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 9F494319806A2DB44419BB8D51E0B430 + */ +public class Light3DLight { + + /** The GL_LIGHTx to be used. */ + private final int glLightNumber; + + /** The light model. */ + private final Light3D lightModel; + + /** Constructor. */ + public Light3DLight(int glLight, Light3D lightModel) { + this.glLightNumber = glLight; + this.lightModel = lightModel; + } + + /** Enables the light in GL. */ + public void enableLight() { + GLPrimitives.enableLight(glLightNumber, lightModel); + } + + /** Disables the light in GL. */ + public void disableLight() { + glDisable(glLightNumber); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/CompositeViewObject.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/CompositeViewObject.java new file mode 100644 index 0000000000000000000000000000000000000000..433b0873c0a8e7591a61dc05ab12421adc57f571 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/CompositeViewObject.java @@ -0,0 +1,53 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +import java.util.ArrayList; +import java.util.List; + +import org.fortiss.tooling.graphics3D.ui.picker.ModelObjectPicker; + +/** + * Composite for {@link ViewObjectBase model objects} forwarding rendering and picking calls to + * component objects. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: D3F8BDCBB89A0D376ED987F07023EC68 + */ +public class CompositeViewObject extends ViewObjectBase { + /** The component objects. */ + private final List<ViewObjectBase> objects = new ArrayList<ViewObjectBase>(); + + /** {@inheritDoc} */ + @Override + public void renderObject() { + for(ViewObjectBase o : objects) { + o.renderObject(); + } + } + + /** {@inheritDoc} */ + @Override + public void renderObjectForPicking(ModelObjectPicker picker) { + for(ViewObjectBase o : objects) { + o.renderObjectForPicking(picker); + } + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/Graph3DViewObject.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/Graph3DViewObject.java new file mode 100644 index 0000000000000000000000000000000000000000..3d31283b6561a8cd5fe849fc6228f4099057f018 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/Graph3DViewObject.java @@ -0,0 +1,133 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.drawLine; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.flushName; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.moveTo; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.prepareName; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.restoreMatrix; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.saveMatrix; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.setColor; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.RED; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.WHITE; +import static org.lwjgl.util.glu.GLU.GLU_FILL; + +import org.fortiss.tooling.graphics3D.model.Color3D; +import org.fortiss.tooling.graphics3D.model.graph.Axis3D; +import org.fortiss.tooling.graphics3D.model.graph.CoordinateSystem3D; +import org.fortiss.tooling.graphics3D.model.graph.Graph3D; +import org.fortiss.tooling.graphics3D.model.graph.GraphLine3D; +import org.fortiss.tooling.graphics3D.model.graph.GraphPoint3D; +import org.fortiss.tooling.graphics3D.ui.picker.ModelObjectPicker; +import org.lwjgl.util.glu.Sphere; + +/** + * View object for {@link Graph3D}. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 7EFCEC92BBCFB59C5C1BEA5F9F2ABFD3 + */ +public class Graph3DViewObject extends ViewObjectBase { + /** The graph model. */ + private final Graph3D graph; + + /** The highlighted model object. */ + private GraphPoint3D highlighted; + + /** Constructor. */ + public Graph3DViewObject(Graph3D graph) { + this.graph = graph; + } + + /** Sets the currently highlighted point. */ + public void setHighlightedPoint(GraphPoint3D point) { + highlighted = point; + } + + /** {@inheritDoc} */ + @Override + public void renderObject() { + renderCoordSys(graph.getCoordinateSystem()); + setColor(WHITE); + for(GraphPoint3D p : graph.getPointsList()) { + if(p == highlighted) { + setColor(RED); + renderPoint(p); + setColor(WHITE); + } else { + renderPoint(p); + } + } + for(GraphLine3D l : graph.getLinesList()) { + drawLine(l.getStart().getPosition(), l.getEnd().getPosition()); + } + } + + /** {@inheritDoc} */ + @Override + public void renderObjectForPicking(ModelObjectPicker picker) { + // only points are pickable + for(GraphPoint3D p : graph.getPointsList()) { + prepareName(p, picker); + renderPoint(p); + flushName(); + } + } + + /** The GLU sphere used for {@link GraphPoint3D} rendering. */ + private static Sphere SPHERE = new Sphere(); + + static { + SPHERE.setDrawStyle(GLU_FILL); + } + + /** Renders the given point. */ + private void renderPoint(GraphPoint3D p) { + saveMatrix(); + moveTo(p.getPosition()); + SPHERE.draw(0.2f, 9, 4); + restoreMatrix(); + } + + /** Renders the coordinate system if present. */ + private void renderCoordSys(CoordinateSystem3D coordinateSystem) { + if(coordinateSystem != null) { + if(coordinateSystem.getXAxis() != null) { + Axis3D a = coordinateSystem.getXAxis(); + renderAxis(a.getColor(), a.getLength(), 0, 0); + } + if(coordinateSystem.getYAxis() != null) { + Axis3D a = coordinateSystem.getYAxis(); + renderAxis(a.getColor(), 0, a.getLength(), 0); + } + if(coordinateSystem.getZAxis() != null) { + Axis3D a = coordinateSystem.getZAxis(); + renderAxis(a.getColor(), 0, 0, a.getLength()); + } + } + } + + /** Renders the axis. */ + private void renderAxis(Color3D color, float x, float y, float z) { + setColor(color); + drawLine(0, 0, 0, x, y, z); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/Object3DViewObject.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/Object3DViewObject.java new file mode 100644 index 0000000000000000000000000000000000000000..ccfe23e7ca03e7168092d6785b0dc60bff6a7be1 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/Object3DViewObject.java @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.drawMaterialGroups; + +import org.fortiss.tooling.graphics3D.model.scene.Object3D; + +/** + * {@link ViewObjectBase} instance for {@link Object3D} models. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 277D271D3EED34F7CEBDA245836C1528 + */ +public class Object3DViewObject extends ViewObjectBase { + /** The model object. */ + private final Object3D model; + + /** Constructor. */ + public Object3DViewObject(Object3D model) { + this.model = model; + } + + /** {@inheritDoc} */ + @Override + public void renderObject() { + drawMaterialGroups(model.getMesh().getMaterialGroupsList()); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/PickableObjectBase.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/PickableObjectBase.java new file mode 100644 index 0000000000000000000000000000000000000000..7530b3fd2e82b21c995dcdc8855e26c7eb63c9fe --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/PickableObjectBase.java @@ -0,0 +1,54 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +import static org.lwjgl.opengl.GL11.glPopName; +import static org.lwjgl.opengl.GL11.glPushName; + +import org.fortiss.tooling.graphics3D.ui.picker.ModelObjectPicker; + +/** + * Base class for {@link ViewObjectBase view objects}, which become pickable by the + * {@link ModelObjectPicker}. Sub-classes may override {@link #renderSimplifiedPickableObject()} to + * provide a simpler shape during the picking render process. The default renders the same object as + * {@link #renderObject()}. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: DD1E015FD10F45DD24F4A92F67902F33 + */ +public abstract class PickableObjectBase extends ViewObjectBase { + + /** {@inheritDoc} */ + @Override + public final void renderObjectForPicking(ModelObjectPicker picker) { + int name = picker.registerPickableObject(this); + glPushName(name); + renderSimplifiedPickableObject(); + glPopName(); + } + + /** + * Renders this object in a simplified version for picking. The default just renders the object + * as usual. Sub-classes may override to provide simpler shapes. + */ + protected void renderSimplifiedPickableObject() { + renderObject(); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/RotatedObject.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/RotatedObject.java new file mode 100644 index 0000000000000000000000000000000000000000..72841c6fc28697b4a8e666ed7cf4ef9ff17dc99f --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/RotatedObject.java @@ -0,0 +1,60 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.restoreMatrix; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.rotate; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.saveMatrix; + +import org.lwjgl.util.vector.Vector3f; + +/** + * Rotates the wrapped object by the given angle at the origin. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: A447FB4D5DC5307470D36A7347352A16 + */ +public class RotatedObject extends WrappedViewObjectBase { + /** The rotation angle. */ + private float angle; + + /** The rotation axis. */ + private final Vector3f axis; + + /** Constructor. */ + public RotatedObject(ViewObjectBase wrapped, float angle, Vector3f axis) { + super(wrapped); + this.angle = angle; + this.axis = axis; + } + + /** {@inheritDoc} */ + @Override + protected void preRendering() { + saveMatrix(); + rotate(angle, axis); + } + + /** {@inheritDoc} */ + @Override + protected void postRendering() { + restoreMatrix(); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/ScaledObject.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/ScaledObject.java new file mode 100644 index 0000000000000000000000000000000000000000..9d41cf8cb51237ebfe28778a897add0fbf3d14f9 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/ScaledObject.java @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.restoreMatrix; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.saveMatrix; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.scale; + +import org.lwjgl.util.vector.Vector3f; + +/** + * Scales the wrapped object by the given factor. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 57BE199D8FDF27A1D0F615CD53FCD32F + */ +public class ScaledObject extends WrappedViewObjectBase { + /** The scale factor. */ + private Vector3f scaleFactor; + + /** Constructor. */ + public ScaledObject(ViewObjectBase wrapped, Vector3f factor) { + super(wrapped); + this.scaleFactor = factor; + } + + /** {@inheritDoc} */ + @Override + protected void preRendering() { + saveMatrix(); + scale(scaleFactor); + } + + /** {@inheritDoc} */ + @Override + protected void postRendering() { + restoreMatrix(); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/ViewObjectBase.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/ViewObjectBase.java new file mode 100644 index 0000000000000000000000000000000000000000..e9dc2856bfb0709385371d27b774f7961f25374b --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/ViewObjectBase.java @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +import org.fortiss.tooling.graphics3D.ui.picker.ModelObjectPicker; + +/** + * Base class for 3D view objects. View objects support two methods for rendering in view and in + * picking mode. The default does not render the object in picking mode. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: C970B9D2F1FF5088B0E7494BE10DA692 + */ +public abstract class ViewObjectBase { + + /** Renders the object. */ + public abstract void renderObject(); + + /** + * Renders the object in picking mode using the given picker. The default renders nothing. + * Sub-classes should override if they represent a pickable object. + * + * @param picker + * the picker requesting a picker rendering run + */ + public void renderObjectForPicking(ModelObjectPicker picker) { + // render nothing + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/WrappedViewObjectBase.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/WrappedViewObjectBase.java new file mode 100644 index 0000000000000000000000000000000000000000..0820e9757490d26d1184a979c9673a8b8662cc67 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/objects/WrappedViewObjectBase.java @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.objects; + +/** + * View object that wraps another object and can provide pre- and post-processing. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 95B8591C26D12367FE0E12C01183EA7B + */ +public abstract class WrappedViewObjectBase extends ViewObjectBase { + + /** The wrapped model object. */ + protected final ViewObjectBase wrapped; + + /** Constructor. */ + public WrappedViewObjectBase(ViewObjectBase wrapped) { + this.wrapped = wrapped; + } + + /** Called before rendering the wrapped object. */ + protected abstract void preRendering(); + + /** Called after rendering the wrapped object. */ + protected abstract void postRendering(); + + /** {@inheritDoc} */ + @Override + public final void renderObject() { + preRendering(); + wrapped.renderObject(); + postRendering(); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/picker/ModelObjectPicker.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/picker/ModelObjectPicker.java new file mode 100644 index 0000000000000000000000000000000000000000..ddfb173602b438ae53e9028ec02f6c028737d144 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/picker/ModelObjectPicker.java @@ -0,0 +1,140 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.picker; + +import static org.lwjgl.BufferUtils.createIntBuffer; +import static org.lwjgl.opengl.GL11.GL_LIGHTING; +import static org.lwjgl.opengl.GL11.GL_MODELVIEW; +import static org.lwjgl.opengl.GL11.GL_PROJECTION; +import static org.lwjgl.opengl.GL11.GL_RENDER; +import static org.lwjgl.opengl.GL11.GL_SELECT; +import static org.lwjgl.opengl.GL11.GL_TEXTURE; +import static org.lwjgl.opengl.GL11.GL_VIEWPORT; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glGetInteger; +import static org.lwjgl.opengl.GL11.glInitNames; +import static org.lwjgl.opengl.GL11.glLoadIdentity; +import static org.lwjgl.opengl.GL11.glMatrixMode; +import static org.lwjgl.opengl.GL11.glPopMatrix; +import static org.lwjgl.opengl.GL11.glPushMatrix; +import static org.lwjgl.opengl.GL11.glRenderMode; +import static org.lwjgl.opengl.GL11.glSelectBuffer; +import static org.lwjgl.util.glu.GLU.gluPerspective; +import static org.lwjgl.util.glu.GLU.gluPickMatrix; + +import java.nio.IntBuffer; +import java.util.HashMap; +import java.util.Map; + +import org.fortiss.tooling.graphics3D.ui.camera.Camera; +import org.fortiss.tooling.graphics3D.ui.objects.ViewObjectBase; +import org.lwjgl.util.vector.Vector3f; + +/** + * Picker implementation for model objects using GL select mode rendering. + * {@link #pickModelObject(int, int, Vector3f, ViewObjectBase)} returns the nearest object. All + * others are discarded. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 4F5B62FD35DFAAEAE994F1C76A03CA27 + */ +public final class ModelObjectPicker { + /** The buffer size for pickable objects. */ + private static final int BUFFER_SIZE = 1024; + + /** The selection buffer. */ + private final IntBuffer selectBuffer = createIntBuffer(BUFFER_SIZE); + /** The viewport buffer. */ + private final IntBuffer viewport = createIntBuffer(16); + + /** The pickable object registry. */ + private final Map<Integer, Object> objectRegistry = new HashMap<Integer, Object>(); + + /** The registry counter. */ + private int registryCounter = 1; + + /** Registers the given object for the current picker run. */ + public int registerPickableObject(Object object) { + int name = registryCounter; + objectRegistry.put(name, object); + registryCounter++; + return name; + } + + /** + * Performs the picking process for the given {@link ViewObjectBase} from the given + * {@link Camera}s view at the given location and returns the picking result or {@code null} if + * nothing was hit. + */ + public Object pickModelObject(int x, int y, Vector3f perspective, ViewObjectBase scene) { + // reset picker + objectRegistry.clear(); + registryCounter = 1; + viewport.clear(); + selectBuffer.clear(); + + glGetInteger(GL_VIEWPORT, viewport); + float aspect = + (float)(viewport.get(2) - viewport.get(0)) / + (float)(viewport.get(3) - viewport.get(1)); + + glSelectBuffer(selectBuffer); + glRenderMode(GL_SELECT); + glInitNames(); + + // setup perspective + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluPickMatrix(x, viewport.get(3) - y, 5.0f, 5.0f, viewport); + gluPerspective(perspective.x, aspect, perspective.y, perspective.z); + + // render objects in picking mode + glMatrixMode(GL_MODELVIEW); + glDisable(GL_TEXTURE); + glDisable(GL_LIGHTING); + scene.renderObjectForPicking(this); + + // restore projection matrix + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + // return to render mode to count hits + int hits = glRenderMode(GL_RENDER); + if(hits > 0) { + int name = selectBuffer.get(3); + int depth = selectBuffer.get(1); + + for(int i = 1; i < hits; i++) { + int idx = i * 4; + int nDepth = selectBuffer.get(idx + 1); + if(nDepth < depth) { + name = selectBuffer.get(idx + 3); + depth = nDepth; + } + } + if(name > 0) { + return objectRegistry.get(name); + } + } + return null; + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/util/FloatBufferUtils.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/util/FloatBufferUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..bad80a2d8b4bdc789e9ca5fd13fa54871c33546e --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/util/FloatBufferUtils.java @@ -0,0 +1,89 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.util; + +import static org.lwjgl.BufferUtils.createFloatBuffer; + +import java.nio.FloatBuffer; + +import org.fortiss.tooling.graphics3D.model.Color3D; +import org.fortiss.tooling.graphics3D.model.Vector3D; + +/** + * Utility methods for handling {@link FloatBuffer} more easily. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: AFD0F65604F06A6F752C5EEB538EC5A4 + */ +public class FloatBufferUtils { + /** Creates a float buffer for the given value array. */ + public static FloatBuffer toFloatBuffer(float[] f) { + FloatBuffer buf = createFloatBuffer(f.length); + buf.put(f); + buf.flip(); + return buf; + } + + /** Creates a float buffer for the given value array. */ + public static FloatBuffer toFloatBuffer(float x, float y, float z) { + FloatBuffer buf = createFloatBuffer(3); + buf.put(x).put(y).put(z).flip(); + return buf; + } + + /** Creates a float buffer for the given value array. */ + public static FloatBuffer toFloatBuffer(float x, float y, float z, float w) { + FloatBuffer buf = createFloatBuffer(4); + buf.put(x).put(y).put(z).put(w).flip(); + return buf; + } + + /** Creates a 3-element float buffer for the given {@link Vector3D}. */ + public static FloatBuffer toFloatBuffer(Vector3D vec) { + if(vec == null) { + return toFloatBuffer(0, 0, 0); + } + return toFloatBuffer(vec.getX(), vec.getY(), vec.getZ()); + } + + /** Creates a 4-element float buffer for the given {@link Vector3D} and the additional element. */ + public static FloatBuffer toFloatBuffer(Vector3D vec, float w) { + if(vec == null) { + return toFloatBuffer(0, 0, 0, 0); + } + return toFloatBuffer(vec.getX(), vec.getY(), vec.getZ(), w); + } + + /** Creates a 3-element float buffer for the given {@link Vector3D}. */ + public static FloatBuffer toFloatBuffer(Color3D vec) { + if(vec == null) { + return toFloatBuffer(0, 0, 0); + } + return toFloatBuffer(vec.getRed(), vec.getGreen(), vec.getBlue()); + } + + /** Creates a 4-element float buffer for the given {@link Vector3D} and the additional element. */ + public static FloatBuffer toFloatBuffer(Color3D vec, float w) { + if(vec == null) { + return toFloatBuffer(0, 0, 0, 0); + } + return toFloatBuffer(vec.getRed(), vec.getGreen(), vec.getBlue(), w); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/util/GLPrimitives.java b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/util/GLPrimitives.java new file mode 100644 index 0000000000000000000000000000000000000000..8858203424f63a1de9ae8611d79fd3bd10c8eb5f --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/src/org/fortiss/tooling/graphics3D/ui/util/GLPrimitives.java @@ -0,0 +1,308 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.graphics3D.ui.util; + +import static org.fortiss.tooling.graphics3D.ui.util.FloatBufferUtils.toFloatBuffer; +import static org.fortiss.tooling.graphics3D.util.Mesh3DModelElementFactory.DEFAULT_MATERIAL; +import static org.lwjgl.BufferUtils.createFloatBuffer; +import static org.lwjgl.opengl.GL11.GL_AMBIENT; +import static org.lwjgl.opengl.GL11.GL_AMBIENT_AND_DIFFUSE; +import static org.lwjgl.opengl.GL11.GL_BACK; +import static org.lwjgl.opengl.GL11.GL_COLOR_MATERIAL; +import static org.lwjgl.opengl.GL11.GL_CULL_FACE; +import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; +import static org.lwjgl.opengl.GL11.GL_DIFFUSE; +import static org.lwjgl.opengl.GL11.GL_FLAT; +import static org.lwjgl.opengl.GL11.GL_FRONT; +import static org.lwjgl.opengl.GL11.GL_LIGHTING; +import static org.lwjgl.opengl.GL11.GL_LIGHT_MODEL_AMBIENT; +import static org.lwjgl.opengl.GL11.GL_LINES; +import static org.lwjgl.opengl.GL11.GL_MODELVIEW; +import static org.lwjgl.opengl.GL11.GL_NICEST; +import static org.lwjgl.opengl.GL11.GL_PERSPECTIVE_CORRECTION_HINT; +import static org.lwjgl.opengl.GL11.GL_POSITION; +import static org.lwjgl.opengl.GL11.GL_SHININESS; +import static org.lwjgl.opengl.GL11.GL_SMOOTH; +import static org.lwjgl.opengl.GL11.GL_SPECULAR; +import static org.lwjgl.opengl.GL11.GL_TRIANGLES; +import static org.lwjgl.opengl.GL11.glBegin; +import static org.lwjgl.opengl.GL11.glClear; +import static org.lwjgl.opengl.GL11.glClearColor; +import static org.lwjgl.opengl.GL11.glClearDepth; +import static org.lwjgl.opengl.GL11.glColor3f; +import static org.lwjgl.opengl.GL11.glColorMaterial; +import static org.lwjgl.opengl.GL11.glCullFace; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glEnd; +import static org.lwjgl.opengl.GL11.glGetFloat; +import static org.lwjgl.opengl.GL11.glHint; +import static org.lwjgl.opengl.GL11.glLight; +import static org.lwjgl.opengl.GL11.glLightModel; +import static org.lwjgl.opengl.GL11.glLineWidth; +import static org.lwjgl.opengl.GL11.glLoadIdentity; +import static org.lwjgl.opengl.GL11.glMaterial; +import static org.lwjgl.opengl.GL11.glMaterialf; +import static org.lwjgl.opengl.GL11.glMatrixMode; +import static org.lwjgl.opengl.GL11.glNormal3f; +import static org.lwjgl.opengl.GL11.glPopMatrix; +import static org.lwjgl.opengl.GL11.glPopName; +import static org.lwjgl.opengl.GL11.glPushMatrix; +import static org.lwjgl.opengl.GL11.glPushName; +import static org.lwjgl.opengl.GL11.glRotatef; +import static org.lwjgl.opengl.GL11.glScalef; +import static org.lwjgl.opengl.GL11.glShadeModel; +import static org.lwjgl.opengl.GL11.glTranslatef; +import static org.lwjgl.opengl.GL11.glVertex3f; + +import java.nio.FloatBuffer; +import java.util.List; + +import org.fortiss.tooling.graphics3D.model.Color3D; +import org.fortiss.tooling.graphics3D.model.Vector3D; +import org.fortiss.tooling.graphics3D.model.mesh.Face3D; +import org.fortiss.tooling.graphics3D.model.mesh.Material3D; +import org.fortiss.tooling.graphics3D.model.mesh.MaterialGroup3D; +import org.fortiss.tooling.graphics3D.model.mesh.Normal3D; +import org.fortiss.tooling.graphics3D.model.mesh.Vertex3D; +import org.fortiss.tooling.graphics3D.model.scene.Light3D; +import org.fortiss.tooling.graphics3D.ui.picker.ModelObjectPicker; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.vector.Vector3f; +import org.lwjgl.util.vector.Vector4f; +import org.newdawn.slick.Color; + +/** + * Utility class for GL primitives like setting colors, drawing lines, triangles, quads, etc. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 29BEEFDEA81964C64956C3DF00EEF580 + */ +public class GLPrimitives { + /** The X unit vector. */ + public static Vector3f X_UNIT_VECTOR = new Vector3f(1.0f, 0, 0); + /** The Y unit vector. */ + public static Vector3f Y_UNIT_VECTOR = new Vector3f(0, 1.0f, 0); + /** The Z unit vector. */ + public static Vector3f Z_UNIT_VECTOR = new Vector3f(0, 0, 1.0f); + + /** The GL_LIGHTx array. */ + public static final int[] GL_LIGHT_NUMBER = new int[] {GL11.GL_LIGHT0, GL11.GL_LIGHT1, + GL11.GL_LIGHT2, GL11.GL_LIGHT3, GL11.GL_LIGHT4, GL11.GL_LIGHT5, GL11.GL_LIGHT6, + GL11.GL_LIGHT7}; + + /** Initializes basic GL properties. */ + public static void initializeGL() { + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glColor3f(1.0f, 0.0f, 0.0f); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glClearDepth(1.0); + glLineWidth(2); + glEnable(GL_DEPTH_TEST); + } + + /** Returns the current transformed origin in model view coordinates in the given vector. */ + public static Vector3f getTransformedOrigin() { + FloatBuffer fb = createFloatBuffer(16); + glGetFloat(GL_MODELVIEW, fb); + return new Vector3f(fb.get(12), fb.get(13), fb.get(14)); + } + + /** Sets the current color. */ + public static void setColor(Color color) { + glColor3f(color.r, color.g, color.b); + } + + /** Sets the current color. */ + public static void setColor(Color3D color) { + glColor3f(color.getRed(), color.getGreen(), color.getBlue()); + } + + /** Applies the given translation. */ + public static void translate(Vector3f t) { + glTranslatef(t.getX(), t.getY(), t.getZ()); + } + + /** Applies the given translation. */ + public static void translate(float x, float y, float z) { + glTranslatef(x, y, z); + } + + /** Applies the given scaling factor. */ + public static void scale(Vector3f scale) { + glScalef(scale.x, scale.y, scale.z); + } + + /** Applies the given rotation angle to the axis. */ + public static void rotate(Vector4f axisAndAngle) { + glRotatef(axisAndAngle.w, axisAndAngle.x, axisAndAngle.y, axisAndAngle.z); + } + + /** Applies the given rotation angle to the given axis. */ + public static void rotate(float angle, Vector3f axis) { + glRotatef(angle, axis.x, axis.y, axis.z); + } + + /** Draws a line between the two vertices. */ + public static void drawLine(Vector3f v1, Vector3f v2) { + drawLine(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z); + } + + /** Draws a line between the two points. */ + public static void drawLine(Vector3D p1, Vector3D p2) { + drawLine(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ()); + } + + /** Draws a line between the two points. */ + public static void drawLine(float x1, float y1, float z1, float x2, float y2, float z2) { + glBegin(GL_LINES); + glVertex3f(x1, y1, z1); + glVertex3f(x2, y2, z2); + glEnd(); + } + + /** Draws the given list of material groups. */ + public static void drawMaterialGroups(List<MaterialGroup3D> groups) { + for(MaterialGroup3D g : groups) { + Material3D mat = g.getMaterial() == null ? DEFAULT_MATERIAL : g.getMaterial(); + setMaterial(mat); + setSmoothShading(g.isSmoothShading()); + drawTriangleFaces(g.getFacesList()); + } + } + + /** Draws the given list of {@link Face3D}s with triangle information. */ + public static void drawTriangleFaces(List<Face3D> faces) { + glBegin(GL_TRIANGLES); + for(Face3D f : faces) { + boolean useNormals = f.getNormalsLength() == 3; + for(int i = 0; i < 3; i++) { + if(useNormals) { + Normal3D n = f.getNormals(i); + glNormal3f(n.getX(), n.getY(), n.getZ()); + } + Vertex3D v = f.getVertices(i); + glVertex3f(v.getX(), v.getY(), v.getZ()); + } + } + glEnd(); + } + + /** Saves the current matrix state. */ + public static void saveMatrix() { + glPushMatrix(); + } + + /** Restores the current matrix state. */ + public static void restoreMatrix() { + glPopMatrix(); + } + + /** Translates the matrix to the given coordinates. */ + public static void moveTo(Vector3f coords) { + glTranslatef(coords.x, coords.y, coords.z); + } + + /** Translates the matrix to the given coordinates. */ + public static void moveTo(Vector3D coords) { + glTranslatef(coords.getX(), coords.getY(), coords.getZ()); + } + + /** Sets the current material data for GL_FRONT faces. */ + public static void setMaterial(FloatBuffer ambient, FloatBuffer diffuse, FloatBuffer specular, + float specularCoeff) { + glDisable(GL_COLOR_MATERIAL); + glMaterial(GL_FRONT, GL_AMBIENT, ambient); + glMaterial(GL_FRONT, GL_DIFFUSE, diffuse); + glMaterial(GL_FRONT, GL_SPECULAR, specular); + glMaterialf(GL_FRONT, GL_SHININESS, specularCoeff); + } + + /** Sets the current material data for GL_FRONT faces. */ + public static void setMaterial(Material3D mat) { + setMaterial(toFloatBuffer(mat.getAmbient(), 1.0f), toFloatBuffer(mat.getDiffuse(), 1.0f), + toFloatBuffer(mat.getSpecular(), 1.0f), mat.getSpecularCoeff()); + } + + /** Enables the light with the given number and properties. */ + public static void enableLight(int glLightNumber, FloatBuffer lightPosition, + FloatBuffer ambient, FloatBuffer diffuse, FloatBuffer specular) { + glEnable(glLightNumber); + glLight(glLightNumber, GL_POSITION, lightPosition); + glLight(glLightNumber, GL_AMBIENT, ambient); + glLight(glLightNumber, GL_DIFFUSE, diffuse); + glLight(glLightNumber, GL_SPECULAR, specular); + } + + /** Enables the given light with the given number and model data. */ + public static void enableLight(int glLightNumber, Light3D light) { + enableLight(glLightNumber, toFloatBuffer(light.getPosition(), 1.0f), + toFloatBuffer(light.getAmbient(), 1.0f), toFloatBuffer(light.getDiffuse(), 1.0f), + toFloatBuffer(light.getSpecular(), 1.0f)); + } + + /** Clears the canvas with the given RGB color. */ + public static void clearCanvasAndLoadIdentity(Color color) { + glMatrixMode(GL_MODELVIEW); + glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); + glClearColor(color.r, color.g, color.b, 1.0f); + loadIdentity(); + } + + /** Loads the identity matrix. */ + public static void loadIdentity() { + glLoadIdentity(); + } + + /** Prepare a name for the given object and picker. */ + public static void prepareName(Object obj, ModelObjectPicker picker) { + int name = picker.registerPickableObject(obj); + glPushName(name); + } + + /** Flushes the last name. */ + public static void flushName() { + glPopName(); + } + + /** Enables culling for back polygons (i.e. only front faces are considered for lighting. */ + public static void enableBackCulling() { + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + } + + /** Enables lighting with the given ambient intensity. */ + public static void enableLighting(Color3D col) { + glEnable(GL_LIGHTING); + FloatBuffer ambient = toFloatBuffer(col.getRed(), col.getGreen(), col.getBlue(), 1.0f); + glLightModel(GL_LIGHT_MODEL_AMBIENT, ambient); + } + + /** Enables color material for front faces and ambient and diffuse light components. */ + public static void enableColorMaterial() { + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + } + + /** Sets the smoothness shading mode. */ + public static void setSmoothShading(boolean smooth) { + glShadeModel(smooth ? GL_SMOOTH : GL_FLAT); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/test-src/test/org/fortiss/tooling/graphics3D/ui/Test3DEditor.java b/org.fortiss.tooling.graphicsGL.ui/trunk/test-src/test/org/fortiss/tooling/graphics3D/ui/Test3DEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..c0c837a6ad98bf573ba435103dc2524a1dbc23a5 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/test-src/test/org/fortiss/tooling/graphics3D/ui/Test3DEditor.java @@ -0,0 +1,213 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package test.org.fortiss.tooling.graphics3D.ui; + +import static org.eclipse.swt.SWT.ARROW_DOWN; +import static org.eclipse.swt.SWT.ARROW_LEFT; +import static org.eclipse.swt.SWT.ARROW_RIGHT; +import static org.eclipse.swt.SWT.ARROW_UP; +import static org.eclipse.swt.SWT.PAGE_DOWN; +import static org.eclipse.swt.SWT.PAGE_UP; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.enableColorMaterial; +import static org.fortiss.tooling.graphics3D.ui.util.GLPrimitives.enableLighting; +import static org.fortiss.tooling.graphics3D.util.Graph3DModelElementFactory.axis; +import static org.fortiss.tooling.graphics3D.util.Graph3DModelElementFactory.coordSystem; +import static org.fortiss.tooling.graphics3D.util.Graph3DModelElementFactory.graph; +import static org.fortiss.tooling.graphics3D.util.Graph3DModelElementFactory.graphLine; +import static org.fortiss.tooling.graphics3D.util.Graph3DModelElementFactory.graphPoint; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.BLUE; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.GREEN; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.RED; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.WHITE; +import static org.fortiss.tooling.graphics3D.util.Graphics3DModelElementFactory.color; +import static org.fortiss.tooling.graphics3D.util.Scene3DModelElementFactory.light3D; +import static org.lwjgl.opengl.GL11.GL_LIGHT0; +import static org.lwjgl.opengl.GL11.GL_LIGHT1; +import static org.lwjgl.opengl.GL11.GL_LIGHT2; +import static org.lwjgl.opengl.GL11.GL_LIGHT3; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseEvent; +import org.fortiss.tooling.graphics3D.model.Color3D; +import org.fortiss.tooling.graphics3D.model.Vector3D; +import org.fortiss.tooling.graphics3D.model.graph.CoordinateSystem3D; +import org.fortiss.tooling.graphics3D.model.graph.Graph3D; +import org.fortiss.tooling.graphics3D.model.graph.GraphLine3D; +import org.fortiss.tooling.graphics3D.model.graph.GraphPoint3D; +import org.fortiss.tooling.graphics3D.ui.camera.Camera; +import org.fortiss.tooling.graphics3D.ui.camera.MovingCameraWithPitchAndYaw; +import org.fortiss.tooling.graphics3D.ui.editor.Graphical3DEditorBase; +import org.fortiss.tooling.graphics3D.ui.light.Light3DLight; +import org.fortiss.tooling.graphics3D.ui.objects.Graph3DViewObject; +import org.fortiss.tooling.graphics3D.ui.objects.ViewObjectBase; +import org.fortiss.tooling.kernel.model.IProjectRootElement; + +/** + * Test editor for 3d canvas display. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: C1DEE860EDFB7F388FEECC831432B425 + */ +public class Test3DEditor extends Graphical3DEditorBase<IProjectRootElement> { + /** The ambient intensity. */ + private static final Color3D AMBIENT_INTENSITY = color(0.8f, 0.8f, 0.8f); + + /** The axis length. */ + private static final float AXIS_LENGTH = 20.0f; + + /** Origin light. */ + private Light3DLight oLight = new Light3DLight(GL_LIGHT0, light3D(0, 0, 0, WHITE)); + + /** X axis light. */ + private Light3DLight xLight = new Light3DLight(GL_LIGHT1, light3D(AXIS_LENGTH, 0, 0, RED)); + + /** Y axis light. */ + private Light3DLight yLight = new Light3DLight(GL_LIGHT2, light3D(0, AXIS_LENGTH, 0, GREEN)); + + /** Z axis light. */ + private Light3DLight zLight = new Light3DLight(GL_LIGHT3, light3D(0, 0, AXIS_LENGTH, BLUE)); + + /** The camera. */ + private MovingCameraWithPitchAndYaw camera = new MovingCameraWithPitchAndYaw(); + + /** The graph model. */ + private Graph3D graphModel; + + /** The graph display. */ + private Graph3DViewObject graphDisplay; + + /** Constructor. */ + public Test3DEditor() { + setupTestData(); + graphDisplay = new Graph3DViewObject(graphModel); + camera.setPosition(1.0f, 1.0f, 1.0f); + } + + /** {@inheritDoc} */ + @Override + protected void beginRenderLoop() { + enableLighting(AMBIENT_INTENSITY); + oLight.enableLight(); + xLight.enableLight(); + yLight.enableLight(); + zLight.enableLight(); + enableColorMaterial(); + } + + /** {@inheritDoc} */ + @Override + protected ViewObjectBase getSceneModelObject() { + return graphDisplay; + } + + /** {@inheritDoc} */ + @Override + protected Camera getCamera() { + return camera; + } + + /** {@inheritDoc} */ + @Override + public void mouseDoubleClick(MouseEvent e) { + // camera.switchLight(); + } + + /** {@inheritDoc} */ + @Override + public void mouseMove(MouseEvent e) { + pickX = e.x; + pickY = e.y; + // statusBarItem.setText("moved to " + pickX + ":" + pickY); + } + + /** {@inheritDoc} */ + @Override + protected void pickTargetChanged() { + if(pickTarget instanceof GraphPoint3D) { + GraphPoint3D p = (GraphPoint3D)pickTarget; + graphDisplay.setHighlightedPoint(p); + Vector3D v = p.getPosition(); + statusBarItem.setText("x:" + v.getX() + ",y:" + v.getY() + ",z:" + v.getZ()); + } + } + + /** {@inheritDoc} */ + @Override + public void keyReleased(KeyEvent e) { + float speed = 0.5f; + switch(e.keyCode) { + case ARROW_UP: + camera.forward(speed); + break; + case ARROW_DOWN: + camera.backward(speed); + break; + case ARROW_RIGHT: + camera.right(speed); + break; + case ARROW_LEFT: + camera.left(speed); + break; + case PAGE_UP: + camera.up(speed); + break; + case PAGE_DOWN: + camera.down(speed); + break; + } + switch(e.character) { + case 'w': + camera.pitch(15.0f); + break; + case 's': + camera.pitch(-15.0f); + break; + case 'a': + camera.yaw(-15.0f); + break; + case 'd': + camera.yaw(15.0f); + break; + } + } + + /** Setup test data for graph. */ + private void setupTestData() { + // setup test data + List<GraphPoint3D> pts = new ArrayList<GraphPoint3D>(); + List<GraphLine3D> lns = new ArrayList<GraphLine3D>(); + GraphPoint3D last = null; + for(float i = 1; i < 10; i++) { + GraphPoint3D current = graphPoint(i, i, i > 5 ? 10 - i : i); + pts.add(current); + if(last != null) { + lns.add(graphLine(last, current)); + } + last = current; + } + CoordinateSystem3D sys = + coordSystem(axis(AXIS_LENGTH, RED), axis(AXIS_LENGTH, GREEN), + axis(AXIS_LENGTH, BLUE)); + graphModel = graph(sys, pts, lns); + } +} diff --git a/org.fortiss.tooling.graphicsGL.ui/trunk/test-src/test/org/fortiss/tooling/graphics3D/ui/Test3DEditorBinding.java b/org.fortiss.tooling.graphicsGL.ui/trunk/test-src/test/org/fortiss/tooling/graphics3D/ui/Test3DEditorBinding.java new file mode 100644 index 0000000000000000000000000000000000000000..6f19d6ab31090b13e349a85414cab951174cb9a1 --- /dev/null +++ b/org.fortiss.tooling.graphicsGL.ui/trunk/test-src/test/org/fortiss/tooling/graphics3D/ui/Test3DEditorBinding.java @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2012 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package test.org.fortiss.tooling.graphics3D.ui; + +import org.eclipse.ui.IEditorPart; +import org.fortiss.af3.expression.model.DataDictionary; +import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding; + +/** + * Editor binding for {@link Test3DEditor}. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 92549E564D969E70FD6068582B3F5AE7 + */ +public class Test3DEditorBinding implements IModelEditorBinding<DataDictionary> { + + /** {@inheritDoc} */ + @Override + public Class<? extends IEditorPart> getEditorClass() { + return Test3DEditor.class; + } + + /** {@inheritDoc} */ + @Override + public String getLabel() { + return "Test 3D Editor"; + } + + /** {@inheritDoc} */ + @Override + public int getPriority() { + return 0; + } +}