Java tutorial
/* * * Goko * Copyright (C) 2013 PsyKo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.goko.tools.viewer.jogl.utils.render; import java.util.ArrayList; import java.util.List; import javax.media.opengl.GL; import javax.media.opengl.GL3; import javax.vecmath.Color3f; import javax.vecmath.Color4f; import javax.vecmath.Matrix4d; import javax.vecmath.Matrix4f; import javax.vecmath.Point3f; import javax.vecmath.Point4d; import javax.vecmath.Vector3f; import javax.vecmath.Vector4f; import org.apache.commons.collections.CollectionUtils; import org.goko.core.common.exception.GkException; import org.goko.core.common.measure.quantity.Length; import org.goko.core.controller.IGCodeContextProvider; import org.goko.core.controller.event.IGCodeContextListener; import org.goko.core.gcode.rs274ngcv3.context.GCodeContext; import org.goko.core.log.GkLog; import org.goko.core.math.Tuple6b; import org.goko.tools.viewer.jogl.service.JoglUtils; import org.goko.tools.viewer.jogl.service.Layer; import org.goko.tools.viewer.jogl.shaders.EnumGokoShaderProgram; import org.goko.tools.viewer.jogl.shaders.ShaderLoader; import org.goko.tools.viewer.jogl.utils.render.internal.AbstractVboJoglRenderer; /** * Draw the XYZ axis * * @author PsyKo * */ public class GridRenderer extends AbstractVboJoglRenderer implements IGCodeContextListener<GCodeContext> { private static final GkLog LOG = GkLog.getLogger(GridRenderer.class); private String id; private Length majorIncrement; private Length minorIncrement; private Color4f majorUnitColor = new Color4f(0.4f, 0.4f, 0.4f, 1f); private Color4f minorUnitColor = new Color4f(0.4f, 0.4f, 0.4f, 1f); private Color4f originColor = new Color4f(0.8f, 0.8f, 0.8f, 1f); private Tuple6b start; private Tuple6b end; private float majorOpacity; private float minorOpacity; private float axisOpacity; private Matrix4f axisTransformMatrix; private Vector4f normal; private IGCodeContextProvider<GCodeContext> gcodeContextProvider; public GridRenderer(String id, IGCodeContextProvider<GCodeContext> gcodeContextProvider) { this(id, new Tuple6b(-100, -100, 0, JoglUtils.JOGL_UNIT), new Tuple6b(100, 100, 0, JoglUtils.JOGL_UNIT), Length.valueOf(10, JoglUtils.JOGL_UNIT), Length.valueOf(1, JoglUtils.JOGL_UNIT), new Color3f(0.4f, 0.4f, 0.4f), new Color3f(0.4f, 0.4f, 0.4f), 0.5f, 0.5f, 0.5f, new Vector4f(0f, 0f, 1f, 0f)); this.gcodeContextProvider = gcodeContextProvider; if (this.gcodeContextProvider != null) { gcodeContextProvider.addObserver(this); } } /** * Constructor */ public GridRenderer(String id, Tuple6b start, Tuple6b end, Length majorIncrement, Length minorIncrement, Color3f majorColor, Color3f minorColor, float minorOpacity, float majorOpacity, float axisOpacity, Vector4f normal) { super(GL.GL_LINES, COLORS | VERTICES); this.id = id; this.setLayerId(Layer.LAYER_GRIDS); this.start = new Tuple6b(); this.start.min(start, end); this.end = new Tuple6b(); this.end.max(start, end); this.majorIncrement = majorIncrement.to(JoglUtils.JOGL_UNIT); this.minorIncrement = minorIncrement.to(JoglUtils.JOGL_UNIT); this.majorUnitColor = new Color4f(majorColor.x, majorColor.y, majorColor.z, majorOpacity); this.minorUnitColor = new Color4f(minorColor.x, minorColor.y, minorColor.z, minorOpacity); this.originColor.w = axisOpacity; this.minorOpacity = minorOpacity; this.majorOpacity = majorOpacity; this.axisOpacity = axisOpacity; this.normal = new Vector4f(normal); buildMatrix(); setUseAlpha(true); } /** (inheritDoc) * @see org.goko.core.viewer.renderer.IViewer3DRenderer#getId() */ @Override public String getCode() { return id; } private void buildGrid() throws GkException { buildMatrix(); List<Point4d> lstVertices = new ArrayList<Point4d>(); List<Color4f> lstColors = new ArrayList<Color4f>(); Tuple6b lclStart6b = new Tuple6b(); lclStart6b.min(start, end); Tuple6b lclEnd6b = new Tuple6b(); lclEnd6b.max(start, end); Tuple6b lclCenter6b = new Tuple6b(0, 0, 0, JoglUtils.JOGL_UNIT); if (gcodeContextProvider != null) { GCodeContext context = gcodeContextProvider.getGCodeContext(); lclCenter6b = context.getCoordinateSystemData(context.getCoordinateSystem()); } // Determine min/max if zero is not in the desired area lclCenter6b = lclCenter6b.max(lclStart6b).min(lclEnd6b); Point3f lclStart = lclStart6b.toPoint3f(JoglUtils.JOGL_UNIT); axisTransformMatrix.transform(lclStart); Point3f lclEnd = lclEnd6b.toPoint3f(JoglUtils.JOGL_UNIT); axisTransformMatrix.transform(lclEnd); Point3f lclCenter = lclCenter6b.toPoint3f(JoglUtils.JOGL_UNIT); axisTransformMatrix.transform(lclCenter); Matrix4d invAxisTransformMatrix = new Matrix4d(axisTransformMatrix); invAxisTransformMatrix.invert(); addVertice(new Point4d(lclCenter.x, lclStart.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclCenter.x, lclEnd.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclStart.x, lclCenter.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclEnd.x, lclCenter.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(originColor); lstColors.add(originColor); lstColors.add(originColor); lstColors.add(originColor); Tuple6b deltaPlus = lclEnd6b.subtract(lclCenter6b).max(new Tuple6b(0, 0, 0, JoglUtils.JOGL_UNIT)); Tuple6b deltaMinus = lclCenter6b.subtract(lclStart6b).max(new Tuple6b(0, 0, 0, JoglUtils.JOGL_UNIT)); // Major divisions int nbStepXPlusMajor = Math.abs(deltaPlus.getX().divide(majorIncrement).intValue()); int nbStepYPlusMajor = Math.abs(deltaPlus.getY().divide(majorIncrement).intValue()); int nbStepZPlusMajor = Math.abs(deltaPlus.getZ().divide(majorIncrement).intValue()); int nbStepXMinusMajor = Math.abs(deltaMinus.getX().divide(majorIncrement).intValue()); int nbStepYMinusMajor = Math.abs(deltaMinus.getY().divide(majorIncrement).intValue()); int nbStepZMinusMajor = Math.abs(deltaMinus.getZ().divide(majorIncrement).intValue()); Vector3f nbStepPlusMajor = new Vector3f(nbStepXPlusMajor, nbStepYPlusMajor, nbStepZPlusMajor); Vector3f nbStepMinusMajor = new Vector3f(nbStepXMinusMajor, nbStepYMinusMajor, nbStepZMinusMajor); axisTransformMatrix.transform(nbStepPlusMajor); axisTransformMatrix.transform(nbStepMinusMajor); double majorIncrementJoglUnit = majorIncrement.doubleValue(JoglUtils.JOGL_UNIT); double minorIncrementJoglUnit = minorIncrement.doubleValue(JoglUtils.JOGL_UNIT); for (int i = 1; i <= nbStepPlusMajor.x; i++) { addVertice(new Point4d(lclCenter.x + i * majorIncrementJoglUnit, lclStart.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclCenter.x + i * majorIncrementJoglUnit, lclEnd.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(majorUnitColor); lstColors.add(majorUnitColor); } for (int i = 1; i <= nbStepMinusMajor.x; i++) { addVertice(new Point4d(lclCenter.x - i * majorIncrementJoglUnit, lclStart.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclCenter.x - i * majorIncrementJoglUnit, lclEnd.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(majorUnitColor); lstColors.add(majorUnitColor); } for (int i = 1; i <= nbStepPlusMajor.y; i++) { addVertice(new Point4d(lclStart.x, lclCenter.y + i * majorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclEnd.x, lclCenter.y + i * majorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(majorUnitColor); lstColors.add(majorUnitColor); } for (int i = 1; i <= nbStepMinusMajor.y; i++) { addVertice(new Point4d(lclStart.x, lclCenter.y - i * majorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclEnd.x, lclCenter.y - i * majorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(majorUnitColor); lstColors.add(majorUnitColor); } // Minor divisions int nbStepXPlusMinor = Math.abs(deltaPlus.getX().divide(minorIncrement).intValue()); int nbStepYPlusMinor = Math.abs(deltaPlus.getY().divide(minorIncrement).intValue()); int nbStepZPlusMinor = Math.abs(deltaPlus.getZ().divide(minorIncrement).intValue()); int nbStepXMinusMinor = Math.abs(deltaMinus.getX().divide(minorIncrement).intValue()); int nbStepYMinusMinor = Math.abs(deltaMinus.getY().divide(minorIncrement).intValue()); int nbStepZMinusMinor = Math.abs(deltaMinus.getZ().divide(minorIncrement).intValue()); Vector3f nbStepPlusMinor = new Vector3f(nbStepXPlusMinor, nbStepYPlusMinor, nbStepZPlusMinor); Vector3f nbStepMinusMinor = new Vector3f(nbStepXMinusMinor, nbStepYMinusMinor, nbStepZMinusMinor); axisTransformMatrix.transform(nbStepPlusMinor); axisTransformMatrix.transform(nbStepMinusMinor); for (int i = 1; i <= nbStepPlusMinor.x; i++) { addVertice(new Point4d(lclCenter.x + i * minorIncrementJoglUnit, lclStart.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclCenter.x + i * minorIncrementJoglUnit, lclEnd.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(minorUnitColor); lstColors.add(minorUnitColor); } for (int i = 1; i <= nbStepMinusMinor.x; i++) { addVertice(new Point4d(lclCenter.x - i * minorIncrementJoglUnit, lclStart.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclCenter.x - i * minorIncrementJoglUnit, lclEnd.y, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(minorUnitColor); lstColors.add(minorUnitColor); } for (int i = 1; i <= nbStepPlusMinor.y; i++) { addVertice(new Point4d(lclStart.x, lclCenter.y + i * minorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclEnd.x, lclCenter.y + i * minorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(minorUnitColor); lstColors.add(minorUnitColor); } for (int i = 1; i <= nbStepMinusMinor.y; i++) { addVertice(new Point4d(lclStart.x, lclCenter.y - i * minorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); addVertice(new Point4d(lclEnd.x, lclCenter.y - i * minorIncrementJoglUnit, lclCenter.z, 1), lstVertices, invAxisTransformMatrix); lstColors.add(minorUnitColor); lstColors.add(minorUnitColor); } // Add X Zero red axis if (normal.dot(new Vector4f(1, 0, 0, 0)) == 0) { addVertice(new Point4d(lclStart.x, 0, 0, 1), lstVertices, null); addVertice(new Point4d(lclEnd.x, 0, 0, 1), lstVertices, null); lstColors.add(new Color4f(1, 0, 0, axisOpacity)); lstColors.add(new Color4f(1, 0, 0, axisOpacity)); } // Add Y Zero green axis if (normal.dot(new Vector4f(0, 1, 0, 0)) == 0) { addVertice(new Point4d(0, lclStart.y, 0, 1), lstVertices, null); addVertice(new Point4d(0, lclEnd.y, 0, 1), lstVertices, null); lstColors.add(new Color4f(0, 1, 0, axisOpacity)); lstColors.add(new Color4f(0, 1, 0, axisOpacity)); } // Add Z Zero Blue axis if (normal.dot(new Vector4f(0, 0, 1, 0)) == 0) { addVertice(new Point4d(0, 0, lclStart.z, 1), lstVertices, null); addVertice(new Point4d(0, 0, lclEnd.z, 1), lstVertices, null); lstColors.add(new Color4f(0, 0, 1, axisOpacity)); lstColors.add(new Color4f(0, 0, 1, axisOpacity)); } setVerticesCount(CollectionUtils.size(lstVertices)); setColorsBuffer(JoglUtils.buildFloatBuffer4f(lstColors)); setVerticesBuffer(JoglUtils.buildFloatBuffer4d(lstVertices)); } private void addVertice(Point4d p, List<Point4d> buffer, Matrix4d invMatrix) { if (invMatrix != null) { invMatrix.transform(p); } buffer.add(p); } /** (inheritDoc) * @see org.goko.tools.viewer.jogl.utils.render.internal.AbstractVboJoglRenderer#buildGeometry() */ @Override protected void buildGeometry() throws GkException { buildGrid(); } /** (inheritDoc) * @see org.goko.tools.viewer.jogl.utils.render.internal.AbstractVboJoglRenderer#loadShaderProgram(javax.media.opengl.GL3) */ @Override protected int loadShaderProgram(GL3 gl) throws GkException { return ShaderLoader.loadShader(gl, EnumGokoShaderProgram.LINE_SHADER); } @Override protected void updateShaderData(GL3 gl) throws GkException { super.updateShaderData(gl); gl.glLineWidth(1); gl.glEnable(GL3.GL_LINE_SMOOTH); } /** (inheritDoc) * @see org.goko.core.controller.event.IGCodeContextListener#onGCodeContextEvent(org.goko.core.gcode.element.IGCodeContext) */ @Override public void onGCodeContextEvent(GCodeContext context) { try { updateGeometry(); } catch (GkException e) { LOG.error(e); } } /** * @return the opacity */ public float getMinorOpacity() { return minorOpacity; } /** * @param opacity the opacity to set */ public void setMinorOpacity(float opacity) { this.minorOpacity = opacity; this.minorUnitColor.w = opacity; } /** * @return the opacity */ public float getMajorOpacity() { return majorOpacity; } /** * @param opacity the opacity to set */ public void setMajorOpacity(float opacity) { this.majorOpacity = opacity; this.majorUnitColor.w = opacity; } /** * @return the opacity */ public float getAxisOpacity() { return axisOpacity; } /** * @param opacity the opacity to set */ public void setAxisOpacity(float opacity) { this.axisOpacity = opacity; this.originColor.w = opacity; } /** * @return the majorIncrement */ public Length getMajorIncrement() { return majorIncrement; } /** * @param majorIncrement the majorIncrement to set */ public void setMajorIncrement(Length majorIncrement) { this.majorIncrement = majorIncrement; } /** * @return the minorIncrement */ public Length getMinorIncrement() { return minorIncrement; } /** * @param minorIncrement the minorIncrement to set */ public void setMinorIncrement(Length minorIncrement) { this.minorIncrement = minorIncrement; } /** * @param majorUnitColor the majorUnitColor to set */ public void setMajorUnitColor(Color3f majorUnitColor) { this.majorUnitColor.x = majorUnitColor.x; this.majorUnitColor.y = majorUnitColor.y; this.majorUnitColor.z = majorUnitColor.z; } /** * @param minorUnitColor the minorUnitColor to set */ public void setMinorUnitColor(Color3f minorUnitColor) { this.minorUnitColor.x = minorUnitColor.x; this.minorUnitColor.y = minorUnitColor.y; this.minorUnitColor.z = minorUnitColor.z; } /** * @return the originColor */ public Color4f getOriginColor() { return originColor; } /** * @param originColor the originColor to set */ public void setOriginColor(Color4f originColor) { this.originColor = originColor; } /** * @return the start */ public Tuple6b getStart() { return start; } /** * @param start the start to set */ public void setStart(Tuple6b start) { this.start = start; } /** * @return the end */ public Tuple6b getEnd() { return end; } /** * @param end the end to set */ public void setEnd(Tuple6b end) { this.end = end; } private void buildMatrix() { if (normal.dot(JoglUtils.X_AXIS) == 1) { // this.axisTransformMatrix = new Matrix4f(new float[] { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }); } else if (normal.dot(JoglUtils.Y_AXIS) == 1) { // this.axisTransformMatrix = new Matrix4f(new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }); } else { // this.axisTransformMatrix = new Matrix4f(new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }); } } /** * @return the normal */ public Vector4f getNormal() { return normal; } /** * @param normal the normal to set */ public void setNormal(Vector4f normal) { this.normal = normal; } }