| /******************************************************************************* |
| * Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| <<<<<<< HEAD |
| * Pierre Allard - initial API and implementation |
| * Regent L'Archeveque |
| * |
| ======= |
| * Pierre Allard, |
| * Regent L'Archeveque - initial API and implementation |
| * |
| >>>>>>> refs/heads/eclipse_pa |
| * SPDX-License-Identifier: EPL-1.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.apogy.addons.ui.jme3.scene_objects; |
| |
| import java.nio.FloatBuffer; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.concurrent.Callable; |
| |
| import javax.vecmath.Color3f; |
| |
| import org.eclipse.apogy.addons.ApogyAddonsPackage; |
| import org.eclipse.apogy.addons.Ruler3DTool; |
| import org.eclipse.apogy.addons.Ruler3dToolNode; |
| import org.eclipse.apogy.addons.ui.Ruler3dToolSceneObject; |
| import org.eclipse.apogy.common.topology.addons.primitives.ui.jme3.JME3PrimitivesUtilities; |
| import org.eclipse.apogy.common.topology.ui.jme3.JME3RenderEngineDelegate; |
| import org.eclipse.apogy.common.topology.ui.jme3.JME3Utilities; |
| import org.eclipse.apogy.common.topology.ui.jme3.scene_objects.DefaultJME3SceneObject; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.jme3.asset.AssetManager; |
| import com.jme3.material.Material; |
| import com.jme3.material.RenderState.FaceCullMode; |
| import com.jme3.math.ColorRGBA; |
| import com.jme3.math.Quaternion; |
| import com.jme3.math.Vector3f; |
| import com.jme3.scene.Geometry; |
| import com.jme3.scene.Mesh; |
| import com.jme3.scene.Mesh.Mode; |
| import com.jme3.scene.Node; |
| import com.jme3.util.BufferUtils; |
| |
| public class Ruler3dToolNodeJME3Object extends DefaultJME3SceneObject<Ruler3dToolNode> |
| implements Ruler3dToolSceneObject { |
| private static final Logger Logger = LoggerFactory.getLogger(Ruler3dToolNodeJME3Object.class); |
| |
| public static final int MAXIMUM_NUMBER_OF_TICK = 100; |
| public static final ColorRGBA FROM_COLOR = ColorRGBA.Red; |
| public static final ColorRGBA TO_COLOR = ColorRGBA.Blue; |
| |
| private Adapter adapter; |
| |
| private AssetManager assetManager; |
| |
| private Node fromTransformNode; |
| private Node toTransformNode; |
| |
| private Geometry fromSphere = null; |
| private Geometry toSphere = null; |
| |
| private Geometry rulerBodyGeometry = null; |
| private Geometry minorTicksGeometry = null; |
| private Geometry majorTicksGeometry = null; |
| |
| private ColorRGBA rulerBodyColor = ColorRGBA.Red; |
| private ColorRGBA minorTicksColor = ColorRGBA.Red; |
| private ColorRGBA majorTicksColor = ColorRGBA.Red; |
| |
| public Ruler3dToolNodeJME3Object(Ruler3dToolNode node, JME3RenderEngineDelegate jme3RenderEngineDelegate) { |
| super(node, jme3RenderEngineDelegate); |
| |
| this.assetManager = this.jme3Application.getAssetManager(); |
| |
| createGeometry(); |
| |
| Job job = new Job("Ruler3dToolNodeJME3Object : Updating Geometry") { |
| @Override |
| protected IStatus run(IProgressMonitor monitor) { |
| // Updates the geometry. |
| requestUpdate(); |
| |
| // Sets initial visibility. |
| setVisible(getTopologyNode().getRuler3DTool().isVisible()); |
| |
| // Register adapter to Tool. |
| getTopologyNode().getRuler3DTool().eAdapters().add(Ruler3dToolNodeJME3Object.this.getAdapter()); |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| job.schedule(); |
| } |
| |
| @Override |
| public void updateGeometry(float tpf) { |
| updateFromTo(); |
| updateRulerBody(); |
| updateMinorTicks(); |
| updateMajorTicks(); |
| } |
| |
| @Override |
| public List<Geometry> getGeometries() { |
| List<Geometry> geometries = new ArrayList<Geometry>(); |
| geometries.add(this.fromSphere); |
| geometries.add(this.toSphere); |
| geometries.add(this.rulerBodyGeometry); |
| geometries.add(this.minorTicksGeometry); |
| geometries.add(this.majorTicksGeometry); |
| return geometries; |
| } |
| |
| @Override |
| public void setVisible(boolean visible) { |
| Logger.info("Setting visibilty to <" + visible + ">."); |
| |
| // Call this on viewer thread. |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| if (!visible && isVisible()) { |
| if (Ruler3dToolNodeJME3Object.this.fromTransformNode != null) |
| Ruler3dToolNodeJME3Object.this.jme3Application.getRootNode() |
| .detachChild(Ruler3dToolNodeJME3Object.this.fromTransformNode); |
| if (Ruler3dToolNodeJME3Object.this.toTransformNode != null) |
| Ruler3dToolNodeJME3Object.this.jme3Application.getRootNode() |
| .detachChild(Ruler3dToolNodeJME3Object.this.toTransformNode); |
| getRoot().detachChild(getAttachmentNode()); |
| } else if (visible && !isVisible()) { |
| if (Ruler3dToolNodeJME3Object.this.fromTransformNode != null) |
| Ruler3dToolNodeJME3Object.this.jme3Application.getRootNode() |
| .attachChild(Ruler3dToolNodeJME3Object.this.fromTransformNode); |
| if (Ruler3dToolNodeJME3Object.this.toTransformNode != null) |
| Ruler3dToolNodeJME3Object.this.jme3Application.getRootNode() |
| .attachChild(Ruler3dToolNodeJME3Object.this.toTransformNode); |
| getRoot().attachChild(getAttachmentNode()); |
| } |
| |
| return null; |
| } |
| }); |
| |
| if (visible) { |
| // Update geometry |
| requestUpdate(); |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| if (Ruler3dToolNodeJME3Object.this.fromTransformNode != null) |
| Ruler3dToolNodeJME3Object.this.jme3Application.getRootNode() |
| .detachChild(Ruler3dToolNodeJME3Object.this.fromTransformNode); |
| if (Ruler3dToolNodeJME3Object.this.toTransformNode != null) |
| Ruler3dToolNodeJME3Object.this.jme3Application.getRootNode() |
| .detachChild(Ruler3dToolNodeJME3Object.this.toTransformNode); |
| |
| Ruler3dToolNodeJME3Object.this.fromTransformNode = null; |
| Ruler3dToolNodeJME3Object.this.toTransformNode = null; |
| Ruler3dToolNodeJME3Object.this.fromSphere = null; |
| Ruler3dToolNodeJME3Object.this.toSphere = null; |
| Ruler3dToolNodeJME3Object.this.rulerBodyGeometry = null; |
| Ruler3dToolNodeJME3Object.this.minorTicksGeometry = null; |
| Ruler3dToolNodeJME3Object.this.majorTicksGeometry = null; |
| |
| if (getTopologyNode() != null && getTopologyNode().getRuler3DTool() != null) { |
| getTopologyNode().getRuler3DTool().eAdapters().remove(Ruler3dToolNodeJME3Object.this.getAdapter()); |
| } |
| |
| // Calls super. |
| Ruler3dToolNodeJME3Object.super.dispose(); |
| |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setRulerColor(final Color3f color) { |
| this.rulerBodyColor = JME3Utilities.convertToColorRGBA(color); |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| ColorRGBA newColor = JME3Utilities.convertToColorRGBA(color); |
| if (Ruler3dToolNodeJME3Object.this.rulerBodyGeometry != null) { |
| Ruler3dToolNodeJME3Object.this.rulerBodyGeometry.getMaterial().setColor("Color", newColor); |
| } |
| |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setMinorTicksColor(Color3f color) { |
| this.minorTicksColor = JME3Utilities.convertToColorRGBA(color); |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| ColorRGBA newColor = JME3Utilities.convertToColorRGBA(color); |
| if (Ruler3dToolNodeJME3Object.this.minorTicksGeometry != null) { |
| Ruler3dToolNodeJME3Object.this.minorTicksGeometry.getMaterial().setColor("Color", newColor); |
| } |
| |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setMajorTicksColor(Color3f color) { |
| this.majorTicksColor = JME3Utilities.convertToColorRGBA(color); |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| ColorRGBA newColor = JME3Utilities.convertToColorRGBA(color); |
| if (Ruler3dToolNodeJME3Object.this.majorTicksGeometry != null) { |
| Ruler3dToolNodeJME3Object.this.majorTicksGeometry.getMaterial().setColor("Color", newColor); |
| } |
| |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setMinorTickSpacing(float minorTickSpacing) { |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| updateMinorTicks(); |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setMajorTickSpacing(float majorTickSpacing) { |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| updateMajorTicks(); |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setMinorTickLength(float minorTickLength) { |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| updateMinorTicks(); |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setMajorTickLength(float majorTickLength) { |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| updateMajorTicks(); |
| return null; |
| } |
| }); |
| } |
| |
| @Override |
| public void setExtremitiesRadius(float newRadius) { |
| this.jme3Application.enqueue(new Callable<Object>() { |
| @Override |
| public Object call() throws Exception { |
| // Detach existing spheres. |
| if (Ruler3dToolNodeJME3Object.this.fromSphere != null) |
| Ruler3dToolNodeJME3Object.this.fromTransformNode |
| .detachChild(Ruler3dToolNodeJME3Object.this.fromSphere); |
| if (Ruler3dToolNodeJME3Object.this.toSphere != null) |
| Ruler3dToolNodeJME3Object.this.toTransformNode.detachChild(Ruler3dToolNodeJME3Object.this.toSphere); |
| |
| if (newRadius >= 0) { |
| // Creates new spheres |
| Ruler3dToolNodeJME3Object.this.fromSphere = JME3PrimitivesUtilities.createSphere(newRadius, |
| Ruler3dToolNodeJME3Object.this.assetManager); |
| Ruler3dToolNodeJME3Object.this.fromSphere.setMaterial(createFromSphereMaterial()); |
| |
| Ruler3dToolNodeJME3Object.this.toSphere = JME3PrimitivesUtilities.createSphere(newRadius, |
| Ruler3dToolNodeJME3Object.this.assetManager); |
| Ruler3dToolNodeJME3Object.this.toSphere.setMaterial(createToSphereMaterial()); |
| |
| // Attaches the spheres. |
| Ruler3dToolNodeJME3Object.this.fromTransformNode |
| .attachChild(Ruler3dToolNodeJME3Object.this.fromSphere); |
| Ruler3dToolNodeJME3Object.this.toTransformNode.attachChild(Ruler3dToolNodeJME3Object.this.toSphere); |
| } |
| |
| return null; |
| } |
| }); |
| } |
| |
| private void createGeometry() { |
| this.rulerBodyColor = JME3Utilities.convertToColorRGBA(getTopologyNode().getRuler3DTool().getRulerColor()); |
| this.minorTicksColor = JME3Utilities.convertToColorRGBA(getTopologyNode().getRuler3DTool().getMinorTickColor()); |
| this.majorTicksColor = JME3Utilities.convertToColorRGBA(getTopologyNode().getRuler3DTool().getMajorTickColor()); |
| |
| // Creates the from node. |
| this.fromTransformNode = new Node("Ruler From"); |
| this.jme3Application.getRootNode().attachChild(this.fromTransformNode); |
| |
| // Creates the to node. |
| this.toTransformNode = new Node("Ruler To"); |
| this.jme3Application.getRootNode().attachChild(this.toTransformNode); |
| |
| // Creates the ruler body and attaches it to the from node. |
| this.rulerBodyGeometry = createRulerBodyGeometry(); |
| this.fromTransformNode.attachChild(this.rulerBodyGeometry); |
| |
| // Creates minor ticks |
| this.minorTicksGeometry = createMinorTicksGeometry(); |
| this.fromTransformNode.attachChild(this.minorTicksGeometry); |
| |
| // Creates major ticks |
| this.majorTicksGeometry = createMajorTicksGeometry(); |
| this.fromTransformNode.attachChild(this.majorTicksGeometry); |
| |
| // Adds the extremities. |
| this.fromSphere = JME3PrimitivesUtilities |
| .createSphere((float) getTopologyNode().getRuler3DTool().getExtremitiesRadius(), this.assetManager); |
| this.fromSphere.setMaterial(createFromSphereMaterial()); |
| this.fromTransformNode.attachChild(this.fromSphere); |
| |
| this.toSphere = JME3PrimitivesUtilities |
| .createSphere((float) getTopologyNode().getRuler3DTool().getExtremitiesRadius(), this.assetManager); |
| this.toSphere.setMaterial(createToSphereMaterial()); |
| this.toTransformNode.attachChild(this.toSphere); |
| } |
| |
| private Geometry createRulerBodyGeometry() { |
| Geometry geometry = new Geometry("Ruler Body", getRulerBodyMesh()); |
| geometry.setMaterial(createRulerBodyMaterial()); |
| return geometry; |
| } |
| |
| private Material createRulerBodyMaterial() { |
| Material mat = new Material(getApplication().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); |
| mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); |
| mat.setColor("Color", this.rulerBodyColor); |
| return mat; |
| } |
| |
| private Mesh getRulerBodyMesh() { |
| Mesh mesh = new Mesh(); |
| mesh.setMode(Mode.Lines); |
| |
| List<Vector3f> verticesList = new ArrayList<Vector3f>(); |
| List<Integer> indexesList = new ArrayList<Integer>(); |
| |
| verticesList.add(new Vector3f()); |
| verticesList.add(new Vector3f()); |
| |
| indexesList.add(new Integer(0)); |
| indexesList.add(new Integer(1)); |
| |
| mesh = new Mesh(); |
| mesh.setMode(Mode.Lines); |
| mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Position, 3, |
| BufferUtils.createFloatBuffer(JME3Utilities.convertToFloatArray(verticesList))); |
| mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Index, 2, |
| BufferUtils.createIntBuffer(JME3Utilities.convertToIntArray(indexesList))); |
| mesh.updateBound(); |
| mesh.updateCounts(); |
| |
| return mesh; |
| } |
| |
| private void updateFromTo() { |
| if (getTopologyNode().getRuler3DTool().getFromNode() != null) { |
| this.fromTransformNode.setLocalTranslation(JME3Utilities |
| .convertToVector3f(getTopologyNode().getRuler3DTool().getFromAbsolutePosition().asTuple3d())); |
| } else { |
| // TODO Detach from scene ? |
| } |
| |
| if (getTopologyNode().getRuler3DTool().getToNode() != null) { |
| this.toTransformNode.setLocalTranslation(JME3Utilities |
| .convertToVector3f(getTopologyNode().getRuler3DTool().getToAbsolutePosition().asTuple3d())); |
| } else { |
| // TODO Detach from scene ? |
| } |
| } |
| |
| private void updateRulerBody() { |
| if (getTopologyNode().getRuler3DTool().getFromNode() != null |
| && getTopologyNode().getRuler3DTool().getToNode() != null) { |
| |
| Vector3f v = this.toTransformNode.getWorldTranslation() |
| .subtract(this.fromTransformNode.getWorldTranslation()); |
| |
| FloatBuffer vertices = this.rulerBodyGeometry.getMesh() |
| .getFloatBuffer(com.jme3.scene.VertexBuffer.Type.Position); |
| vertices.rewind(); |
| vertices.put(0f); |
| vertices.put(0f); |
| vertices.put(0f); |
| |
| vertices.put(v.x); |
| vertices.put(v.y); |
| vertices.put(v.z); |
| |
| this.rulerBodyGeometry.getMesh().setBuffer(com.jme3.scene.VertexBuffer.Type.Position, 3, vertices); |
| this.rulerBodyGeometry.getMesh().updateBound(); |
| this.rulerBodyGeometry.getMesh().updateCounts(); |
| |
| // Re-Attaches the geometry if it has been previously detached. |
| if (!this.fromTransformNode.getChildren().contains(this.rulerBodyGeometry)) { |
| this.fromTransformNode.attachChild(this.rulerBodyGeometry); |
| } |
| } else { |
| // Detach the geometry from the scene. |
| this.fromTransformNode.detachChild(this.rulerBodyGeometry); |
| } |
| } |
| |
| private Geometry createMinorTicksGeometry() { |
| Geometry geometry = new Geometry("Ruler Minor Ticks", createMinorTicksMesh()); |
| geometry.setMaterial(createMinorTicksMaterial()); |
| return geometry; |
| } |
| |
| private Material createMinorTicksMaterial() { |
| Material mat = new Material(getApplication().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); |
| mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); |
| mat.setColor("Color", this.minorTicksColor); |
| return mat; |
| } |
| |
| private Mesh createMinorTicksMesh() { |
| Mesh mesh = new Mesh(); |
| mesh.setMode(Mode.Lines); |
| |
| List<Vector3f> verticesList = new ArrayList<Vector3f>(); |
| List<Integer> indexesList = new ArrayList<Integer>(); |
| |
| for (int i = 0; i < MAXIMUM_NUMBER_OF_TICK; i++) { |
| Vector3f p1 = new Vector3f(i, 0, -0.001f); |
| Vector3f p2 = new Vector3f(i, 0, 0.001f); |
| Vector3f p3 = new Vector3f(i, -0.001f, 0); |
| Vector3f p4 = new Vector3f(i, 0.001f, 0); |
| |
| verticesList.add(p1); |
| verticesList.add(p2); |
| verticesList.add(p3); |
| verticesList.add(p4); |
| |
| // First Line. |
| indexesList.add(new Integer(verticesList.indexOf(p1))); |
| indexesList.add(new Integer(verticesList.indexOf(p2))); |
| |
| // Second Line. |
| indexesList.add(new Integer(verticesList.indexOf(p3))); |
| indexesList.add(new Integer(verticesList.indexOf(p4))); |
| } |
| |
| mesh = new Mesh(); |
| mesh.setMode(Mode.Lines); |
| mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Position, 3, |
| BufferUtils.createFloatBuffer(JME3Utilities.convertToFloatArray(verticesList))); |
| mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Index, 2, |
| BufferUtils.createIntBuffer(JME3Utilities.convertToIntArray(indexesList))); |
| mesh.updateBound(); |
| mesh.updateCounts(); |
| |
| return mesh; |
| } |
| |
| private void updateMinorTicks() { |
| if (getTopologyNode().getRuler3DTool().getFromNode() != null |
| && getTopologyNode().getRuler3DTool().getToNode() != null) { |
| Vector3f v = this.toTransformNode.getWorldTranslation() |
| .subtract(this.fromTransformNode.getWorldTranslation()); |
| float length = v.length(); |
| |
| FloatBuffer vertices = this.minorTicksGeometry.getMesh() |
| .getFloatBuffer(com.jme3.scene.VertexBuffer.Type.Position); |
| vertices.rewind(); |
| |
| // Place a line at the from. |
| float tickIncrement = (float) getTopologyNode().getRuler3DTool().getMinorTickSpacing(); |
| if (tickIncrement <= 0) |
| return; |
| |
| int numberOfTicks = 0; |
| float tickZ = (float) getTopologyNode().getRuler3DTool().getMinorTickLength() / 2.0f; |
| |
| float position = 0; |
| while (position <= length && numberOfTicks < MAXIMUM_NUMBER_OF_TICK) { |
| Vector3f p1 = new Vector3f(position, 0, tickZ); |
| Vector3f p2 = new Vector3f(position, 0, -tickZ); |
| Vector3f p3 = new Vector3f(position, tickZ, 0); |
| Vector3f p4 = new Vector3f(position, -tickZ, 0); |
| |
| vertices.put(p1.x); |
| vertices.put(p1.y); |
| vertices.put(p1.z); |
| |
| vertices.put(p2.x); |
| vertices.put(p2.y); |
| vertices.put(p2.z); |
| |
| vertices.put(p3.x); |
| vertices.put(p3.y); |
| vertices.put(p3.z); |
| |
| vertices.put(p4.x); |
| vertices.put(p4.y); |
| vertices.put(p4.z); |
| |
| position += tickIncrement; |
| numberOfTicks++; |
| } |
| |
| // Sets the remaining ticks at 0 |
| while (numberOfTicks < MAXIMUM_NUMBER_OF_TICK) { |
| // Puts the 4 vertex of each tick to zero. |
| for (int i = 0; i < 4; i++) { |
| vertices.put(0); |
| vertices.put(0); |
| vertices.put(0); |
| } |
| |
| numberOfTicks++; |
| } |
| |
| // Updates the mesh. |
| this.minorTicksGeometry.getMesh().setBuffer(com.jme3.scene.VertexBuffer.Type.Position, 3, vertices); |
| this.minorTicksGeometry.getMesh().updateBound(); |
| this.minorTicksGeometry.getMesh().updateCounts(); |
| |
| // Re-Attaches the geometry if it has been previously detached. |
| if (!this.fromTransformNode.getChildren().contains(this.minorTicksGeometry)) { |
| this.fromTransformNode.attachChild(this.minorTicksGeometry); |
| } |
| |
| // Orients the geometry |
| Quaternion rot = getQuarternionV1ToV2(new Vector3f(1, 0, 0), v.normalize()); |
| this.minorTicksGeometry.setLocalRotation(rot); |
| } else { |
| // Detach the geometry from the scene. |
| this.fromTransformNode.detachChild(this.minorTicksGeometry); |
| } |
| |
| } |
| |
| private Geometry createMajorTicksGeometry() { |
| Geometry geometry = new Geometry("Ruler Major Ticks", createMajorTicksMesh()); |
| geometry.setMaterial(createMajorTicksMaterial()); |
| return geometry; |
| } |
| |
| private Material createMajorTicksMaterial() { |
| Material mat = new Material(getApplication().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); |
| mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); |
| mat.setColor("Color", this.majorTicksColor); |
| return mat; |
| } |
| |
| private Mesh createMajorTicksMesh() { |
| Mesh mesh = new Mesh(); |
| mesh.setMode(Mode.Lines); |
| |
| List<Vector3f> verticesList = new ArrayList<Vector3f>(); |
| List<Integer> indexesList = new ArrayList<Integer>(); |
| |
| for (int i = 0; i < MAXIMUM_NUMBER_OF_TICK; i++) { |
| Vector3f p1 = new Vector3f(i, 0, -0.001f); |
| Vector3f p2 = new Vector3f(i, 0, 0.001f); |
| Vector3f p3 = new Vector3f(i, -0.001f, 0); |
| Vector3f p4 = new Vector3f(i, 0.001f, 0); |
| |
| verticesList.add(p1); |
| verticesList.add(p2); |
| verticesList.add(p3); |
| verticesList.add(p4); |
| |
| // First Line. |
| indexesList.add(new Integer(verticesList.indexOf(p1))); |
| indexesList.add(new Integer(verticesList.indexOf(p2))); |
| |
| // Second Line. |
| indexesList.add(new Integer(verticesList.indexOf(p3))); |
| indexesList.add(new Integer(verticesList.indexOf(p4))); |
| } |
| |
| mesh = new Mesh(); |
| mesh.setMode(Mode.Lines); |
| mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Position, 3, |
| BufferUtils.createFloatBuffer(JME3Utilities.convertToFloatArray(verticesList))); |
| mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Index, 2, |
| BufferUtils.createIntBuffer(JME3Utilities.convertToIntArray(indexesList))); |
| mesh.updateBound(); |
| mesh.updateCounts(); |
| |
| return mesh; |
| } |
| |
| private void updateMajorTicks() { |
| if (getTopologyNode().getRuler3DTool().getFromNode() != null |
| && getTopologyNode().getRuler3DTool().getToNode() != null) { |
| Vector3f v = this.toTransformNode.getWorldTranslation() |
| .subtract(this.fromTransformNode.getWorldTranslation()); |
| float length = v.length(); |
| |
| FloatBuffer vertices = this.majorTicksGeometry.getMesh() |
| .getFloatBuffer(com.jme3.scene.VertexBuffer.Type.Position); |
| vertices.rewind(); |
| |
| // Place a line at the from. |
| float tickIncrement = (float) getTopologyNode().getRuler3DTool().getMajorTickSpacing(); |
| if (tickIncrement <= 0) |
| return; |
| |
| int numberOfTicks = 0; |
| float tickZ = (float) getTopologyNode().getRuler3DTool().getMajorTickLength() / 2.0f; |
| |
| float position = 0; |
| while (position <= length && numberOfTicks < MAXIMUM_NUMBER_OF_TICK) { |
| Vector3f p1 = new Vector3f(position, 0, tickZ); |
| Vector3f p2 = new Vector3f(position, 0, -tickZ); |
| Vector3f p3 = new Vector3f(position, tickZ, 0); |
| Vector3f p4 = new Vector3f(position, -tickZ, 0); |
| |
| vertices.put(p1.x); |
| vertices.put(p1.y); |
| vertices.put(p1.z); |
| |
| vertices.put(p2.x); |
| vertices.put(p2.y); |
| vertices.put(p2.z); |
| |
| vertices.put(p3.x); |
| vertices.put(p3.y); |
| vertices.put(p3.z); |
| |
| vertices.put(p4.x); |
| vertices.put(p4.y); |
| vertices.put(p4.z); |
| |
| position += tickIncrement; |
| numberOfTicks++; |
| } |
| |
| // Sets the remaining ticks at 0 |
| while (numberOfTicks < MAXIMUM_NUMBER_OF_TICK) { |
| // Puts the 4 vertex of each tick to zero. |
| for (int i = 0; i < 4; i++) { |
| vertices.put(0); |
| vertices.put(0); |
| vertices.put(0); |
| } |
| |
| numberOfTicks++; |
| } |
| |
| // Updates the mesh. |
| this.majorTicksGeometry.getMesh().setBuffer(com.jme3.scene.VertexBuffer.Type.Position, 3, vertices); |
| this.majorTicksGeometry.getMesh().updateBound(); |
| this.majorTicksGeometry.getMesh().updateCounts(); |
| |
| // Re-Attaches the geometry if it has been previously detached. |
| if (!this.fromTransformNode.getChildren().contains(this.majorTicksGeometry)) { |
| this.fromTransformNode.attachChild(this.majorTicksGeometry); |
| } |
| |
| // Orients the geometry |
| Quaternion rot = getQuarternionV1ToV2(new Vector3f(1, 0, 0), v.normalize()); |
| this.majorTicksGeometry.setLocalRotation(rot); |
| } else { |
| // Detach the geometry from the scene. |
| this.fromTransformNode.detachChild(this.majorTicksGeometry); |
| } |
| } |
| |
| private Material createFromSphereMaterial() { |
| Material mat = new Material(getApplication().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); |
| mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); |
| mat.setColor("Color", FROM_COLOR); |
| return mat; |
| } |
| |
| private Material createToSphereMaterial() { |
| Material mat = new Material(getApplication().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); |
| mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); |
| mat.setColor("Color", TO_COLOR); |
| return mat; |
| } |
| |
| private Quaternion getQuarternionV1ToV2(Vector3f v1, Vector3f v2) { |
| float angle = v2.angleBetween(v1); |
| |
| // Cross product gives the vector about which to rotate. |
| Vector3f axis = v1.cross(v2); |
| axis = axis.normalize(); |
| Quaternion q = new Quaternion(); |
| q = q.fromAngleAxis(angle, axis); |
| return q; |
| } |
| |
| private Adapter getAdapter() { |
| if (this.adapter == null) { |
| this.adapter = new AdapterImpl() { |
| @Override |
| public void notifyChanged(Notification msg) { |
| if (msg.getNotifier() instanceof Ruler3dToolNode) { |
| int featureId = msg.getFeatureID(Ruler3dToolNode.class); |
| if (featureId == ApogyAddonsPackage.RULER3D_TOOL_NODE__RULER3_DTOOL) { |
| if (msg.getOldValue() instanceof Ruler3dToolNode) { |
| Ruler3dToolNode oldValue = (Ruler3dToolNode) msg.getOldValue(); |
| oldValue.eAdapters().remove(getAdapter()); |
| requestUpdate(); |
| } |
| |
| if (msg.getNewValue() instanceof Ruler3dToolNode) { |
| Ruler3dToolNode newValue = (Ruler3dToolNode) msg.getNewValue(); |
| newValue.eAdapters().add(getAdapter()); |
| requestUpdate(); |
| } |
| } |
| } else if (msg.getNotifier() instanceof Ruler3DTool) { |
| int featureId = msg.getFeatureID(Ruler3DTool.class); |
| switch (featureId) { |
| case ApogyAddonsPackage.RULER3_DTOOL__FROM_ABSOLUTE_POSITION: |
| case ApogyAddonsPackage.RULER3_DTOOL__TO_ABSOLUTE_POSITION: |
| |
| if (isVisible()) { |
| requestUpdate(); |
| } |
| |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__RULER_COLOR: |
| if (msg.getNewValue() instanceof Color3f) { |
| Color3f color = (Color3f) msg.getNewValue(); |
| setRulerColor(color); |
| } |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__MINOR_TICK_SPACING: |
| setMinorTickSpacing((float) msg.getNewDoubleValue()); |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__MAJOR_TICK_SPACING: |
| setMajorTickSpacing((float) msg.getNewDoubleValue()); |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__MINOR_TICK_LENGTH: |
| setMinorTickLength((float) msg.getNewDoubleValue()); |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__MAJOR_TICK_LENGTH: |
| setMajorTickLength((float) msg.getNewDoubleValue()); |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__MINOR_TICK_COLOR: |
| if (msg.getNewValue() instanceof Color3f) { |
| Color3f color = (Color3f) msg.getNewValue(); |
| setMinorTicksColor(color); |
| } |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__MAJOR_TICK_COLOR: |
| if (msg.getNewValue() instanceof Color3f) { |
| Color3f color = (Color3f) msg.getNewValue(); |
| setMajorTicksColor(color); |
| } |
| break; |
| case ApogyAddonsPackage.RULER3_DTOOL__EXTREMITIES_RADIUS: { |
| setExtremitiesRadius((float) msg.getNewDoubleValue()); |
| } |
| break; |
| |
| case ApogyAddonsPackage.SIMPLE3_DTOOL__VISIBLE: |
| setVisible(msg.getNewBooleanValue()); |
| break; |
| |
| case ApogyAddonsPackage.RULER3_DTOOL__RULER3D_TOOL_NODE: |
| |
| // Removes adapter if applicable. |
| if (getTopologyNode().getRuler3DTool() != null) { |
| getTopologyNode().getRuler3DTool().eAdapters().remove(getAdapter()); |
| } |
| |
| if (msg.getNewValue() == null) { |
| dispose(); |
| } |
| break; |
| |
| case ApogyAddonsPackage.SIMPLE3_DTOOL___DISPOSE: |
| dispose(); |
| break; |
| |
| } |
| } |
| } |
| }; |
| } |
| return this.adapter; |
| } |
| } |