private float getCylinderDistance(IVector3f i_rayOrigin, IVector3f i_rayDirection) { // if we hit one of the end caps, we are done float d = getCapDistance(i_rayOrigin, i_rayDirection); if (!Float.isNaN(d)) return d; // it's much quicker to intersect with a cylinder that stands on the // origin and extends along the positive Z axis, so translate the ray // accordingly Vector3f newOrigin = Draw3DCache.getVector3f(); try { Math3D.translate(i_rayOrigin, -0.5f, -0.5f, 0, newOrigin); // now intersect with infinite cylinder along Z axis: float xo = newOrigin.getX(); float yo = newOrigin.getY(); float xd = i_rayDirection.getX(); float yd = i_rayDirection.getY(); float A = xd * xd + yd * yd; float B = 2 * (xo * xd + yo * yd); float C = xo * xo + yo * yo - 0.25f; // radius^2 = 0.25f Math3D.solveQuadraticEquation(A, B, C, TMP_F2); return Math3D.minDistance(TMP_F2); } finally { Draw3DCache.returnVector3f(newOrigin); } }
/** * {@inheritDoc} * * @see org.eclipse.draw3d.AbstractSurface#getYAxis(org.eclipse.draw3d.geometry.Vector3f) */ @Override protected Vector3f getYAxis(Vector3f io_result) { ICamera camera = m_scene.getCamera(); Vector3f yAxis = camera.getUpVector(io_result); yAxis.scale(-1); return yAxis; }
/** * Creates a new cylinder with the given position, number of segments and radius proportions. * * @param i_position3D the position of this shape * @param i_segments the number of segments * @param i_radiusProportions the radius proportions * @param i_superimposed whether this shape is superimposed */ public CylinderShape( IPosition3D i_position3D, int i_segments, float i_radiusProportions, boolean i_superimposed) { super(i_position3D); m_superimposed = i_superimposed; if (i_segments < 3) throw new IllegalArgumentException("cylinders must have at least 3 segments"); if (i_radiusProportions < 0 || i_radiusProportions > 1) throw new IllegalArgumentException("radius proportions must be between 0 and 1, inclusive"); CylinderConfigKey key = new CylinderConfigKey(i_segments, i_radiusProportions); m_config = CONFIG_CACHE.get(key); if (m_config == null) { // calculate top vertices IVector3f[] top = new IVector3f[i_segments]; double c = 0; double a = 2 * Math.PI / i_segments; for (int i = 0; i < i_segments; i++) { float x = (float) Math.cos(c) / 2 + 0.5f; float y = (float) Math.sin(c) / 2 + 0.5f; top[i] = new Vector3fImpl(x, y, 1); c += a; } // calculate bottom vertices IVector3f[] bottom; if (i_radiusProportions == 0) bottom = new IVector3f[] {new Vector3fImpl(0.5f, 0.5f, 0)}; else { bottom = new IVector3f[i_segments]; for (int i = 0; i < top.length; i++) { Vector3f v = new Vector3fImpl(top[i]); if (i_radiusProportions != 1) { v.translate(-0.5f, -0.5f, -1); v.scale(i_radiusProportions); v.translate(0.5f, 0.5f, 0); } else v.translate(0, 0, -1); bottom[i] = v; } } m_config = new CylinderConfig(i_radiusProportions, top, bottom); CONFIG_CACHE.put(key, m_config); } m_fillKey = new CylinderKey(i_segments, i_radiusProportions, false); m_outlineKey = new CylinderKey(i_segments, i_radiusProportions, true); }
private float doGetConeDistance( Vector3f rayOrigin, IVector3f rayDirection, float i_minZ, float i_height) { float sa2 = m_config.getSinApex2(); float ca2 = m_config.getCosApex2(); float xo = rayOrigin.getX(); float yo = rayOrigin.getY(); float zo = rayOrigin.getZ(); float xd = rayDirection.getX(); float yd = rayDirection.getY(); float zd = rayDirection.getZ(); float xo2 = xo * xo; float yo2 = yo * yo; float zo2 = zo * zo; float xd2 = xd * xd; float yd2 = yd * yd; float zd2 = zd * zd; float A = ca2 * (xd2 + yd2) - sa2 * zd2; float B = 2 * (ca2 * (xo * xd + yo * yd) - sa2 * zo * zd); float C = ca2 * (xo2 + yo2) - sa2 * zo2; Math3D.solveQuadraticEquation(A, B, C, TMP_F2); // we must check the z coordinates of possible hits now float d0 = TMP_F2[0]; float d1 = TMP_F2[1]; float zi0 = Float.isNaN(d0) ? Float.NaN : zo + zd * d0; float zi1 = Float.isNaN(d1) ? Float.NaN : zo + zd * d1; boolean v0 = Math3D.in(i_minZ, i_height, zi0); boolean v1 = Math3D.in(i_minZ, i_height, zi1); if (!v0 && !v1) return Float.NaN; if (v0 && v1) return Math3D.minDistance(d0, d1); if (v0) return d0; return d1; }
/** * {@inheritDoc} * * @see org.eclipse.draw3d.AbstractSurface#calculateNormal(org.eclipse.draw3d.geometry.Vector3f) */ @Override protected void calculateNormal(Vector3f io_normal) { io_normal.set(IVector3f.NULLVEC3f); }