private float[] matrixToArray(Matrix... matrices) { double[] temp = new double[16]; int counter = 0; float[] mvF = new float[matrices.length * 16]; for (Matrix m : matrices) { temp = m.toArray(temp, 0, false); for (int i = 0; i < temp.length; i++) { mvF[counter] = (float) temp[i]; counter++; } } return mvF; }
protected void onHorizontalTranslateRel( Angle forwardChange, Angle sideChange, ViewInputAttributes.ActionAttributes actionAttribs) { View view = this.getView(); if (view == null) // include this test to ensure any derived implementation performs it { return; } if (forwardChange.equals(Angle.ZERO) && sideChange.equals(Angle.ZERO)) { return; } if (view instanceof BasicFlyView) { Vec4 forward = view.getForwardVector(); Vec4 up = view.getUpVector(); Vec4 side = forward.transformBy3(Matrix.fromAxisAngle(Angle.fromDegrees(90), up)); forward = forward.multiply3(forwardChange.getDegrees()); side = side.multiply3(sideChange.getDegrees()); Vec4 eyePoint = view.getEyePoint(); eyePoint = eyePoint.add3(forward.add3(side)); Position newPosition = view.getGlobe().computePositionFromPoint(eyePoint); this.setEyePosition(this.uiAnimControl, view, newPosition, actionAttribs); view.firePropertyChange(AVKey.VIEW, null, view); } }
/** * Find out where on the terrain surface the eye would be looking at with the given heading and * pitch angles. * * @param view the orbit view * @param heading heading direction clockwise from north. * @param pitch view pitch angle from the surface normal at the center point. * @return the terrain surface point the view would be looking at in the viewport center. */ protected Vec4 computeSurfacePoint(OrbitView view, Angle heading, Angle pitch) { Globe globe = wwd.getModel().getGlobe(); // Compute transform to be applied to north pointing Y so that it would point in the view // direction // Move coordinate system to view center point Matrix transform = globe.computeSurfaceOrientationAtPosition(view.getCenterPosition()); // Rotate so that the north pointing axes Y will point in the look at direction transform = transform.multiply(Matrix.fromRotationZ(heading.multiply(-1))); transform = transform.multiply(Matrix.fromRotationX(Angle.NEG90.add(pitch))); // Compute forward vector Vec4 forward = Vec4.UNIT_Y.transformBy4(transform); // Return intersection with terrain Intersection[] intersections = wwd.getSceneController().getTerrain().intersect(new Line(view.getEyePoint(), forward)); return (intersections != null && intersections.length != 0) ? intersections[0].getIntersectionPoint() : null; }
protected Matrix transformModelView(Matrix modelView, IDelegateView view) { if (disableHeadTransform) { return modelView; } Vec4 translation = RiftUtils.toVec4(eyePoses[eye].Position); double translationScale = getHeadTranslationScale(view); Quaternion rotation = RiftUtils.toQuaternion(eyePoses[eye].Orientation); Matrix translationM = Matrix.fromTranslation(translation.multiply3(-translationScale)); Matrix rotationM = Matrix.fromQuaternion(rotation.getInverse()); return rotationM.multiply(translationM.multiply(modelView)); }
/** * Compute the bounding screen extent of a rotated rectangle. * * @param rect Rectangle to rotate. * @param x X coordinate of the rotation point. * @param y Y coordinate of the rotation point. * @param rotation Rotation angle. * @return The smallest rectangle that completely contains {@code rect} when rotated by the * specified angle. */ protected Rectangle computeRotatedScreenExtent(Rectangle rect, int x, int y, Angle rotation) { Rectangle r = new Rectangle(rect); // Translate the rectangle to the rotation point. r.translate(-x, -y); // Compute corner points Vec4[] corners = { new Vec4(r.getMaxX(), r.getMaxY()), new Vec4(r.getMaxX(), r.getMinY()), new Vec4(r.getMinX(), r.getMaxY()), new Vec4(r.getMinX(), r.getMinY()) }; // Rotate the rectangle Matrix rotationMatrix = Matrix.fromRotationZ(rotation); for (int i = 0; i < corners.length; i++) { corners[i] = corners[i].transformBy3(rotationMatrix); } // Find the bounding rectangle of rotated points. int minX = Integer.MAX_VALUE; int minY = Integer.MAX_VALUE; int maxX = -Integer.MAX_VALUE; int maxY = -Integer.MAX_VALUE; for (Vec4 v : corners) { if (v.x > maxX) maxX = (int) v.x; if (v.x < minX) minX = (int) v.x; if (v.y > maxY) maxY = (int) v.y; if (v.y < minY) minY = (int) v.y; } // Set bounds and translate the rectangle back to where it started. r.setBounds(minX, minY, maxX - minX, maxY - minY); r.translate(x, y); return r; }
@Override protected void applyModelviewTransform(DrawContext dc, SurfaceTileDrawContext sdc) { // Apply the geographic to surface tile coordinate transform. Matrix modelview = sdc.getModelviewMatrix(); dc.getGL().glMultMatrixd(modelview.toArray(new double[16], 0, false), 0); }
/** * Compute the label's screen position from its geographic position. * * @param dc Current draw context. */ protected void computeGeometry(DrawContext dc) { // Project the label position onto the viewport Position pos = this.getPosition(); if (pos == null) return; this.placePoint = dc.computeTerrainPoint(pos.getLatitude(), pos.getLongitude(), 0); this.screenPlacePoint = dc.getView().project(this.placePoint); this.eyeDistance = this.placePoint.distanceTo3(dc.getView().getEyePoint()); boolean orientationReversed = false; if (this.orientationPosition != null) { // Project the orientation point onto the screen Vec4 orientationPlacePoint = dc.computeTerrainPoint( this.orientationPosition.getLatitude(), this.orientationPosition.getLongitude(), 0); Vec4 orientationScreenPoint = dc.getView().project(orientationPlacePoint); this.rotation = this.computeRotation(this.screenPlacePoint, orientationScreenPoint); // The orientation is reversed if the orientation point falls to the right of the screen // point. Text is // never drawn upside down, so when the orientation is reversed the text flips vertically to // keep the text // right side up. orientationReversed = (orientationScreenPoint.x <= this.screenPlacePoint.x); } this.computeBoundsIfNeeded(dc); Offset offset = this.getOffset(); Point2D offsetPoint = offset.computeOffset(this.bounds.getWidth(), this.bounds.getHeight(), null, null); // If a rotation is applied to the text, then rotate the offset as well. An offset in the x // direction // will move the text along the orientation line, and a offset in the y direction will move the // text // perpendicular to the orientation line. if (this.rotation != null) { double dy = offsetPoint.getY(); // If the orientation is reversed we need to adjust the vertical offset to compensate for the // flipped // text. For example, if the offset normally aligns the top of the text with the place point // then without // this adjustment the bottom of the text would align with the place point when the // orientation is // reversed. if (orientationReversed) { dy = -(dy + this.bounds.getHeight()); } Vec4 pOffset = new Vec4(offsetPoint.getX(), dy); Matrix rot = Matrix.fromRotationZ(this.rotation.multiply(-1)); pOffset = pOffset.transformBy3(rot); offsetPoint = new Point((int) pOffset.getX(), (int) pOffset.getY()); } int x = (int) (this.screenPlacePoint.x + offsetPoint.getX()); int y = (int) (this.screenPlacePoint.y - offsetPoint.getY()); this.screenPoint = new Point(x, y); this.screenExtent = this.computeTextExtent(x, y, this.rotation); }
protected int computeCartesianPolygon( Globe globe, List<? extends LatLon> locations, List<Boolean> edgeFlags, Vec4[] points, Boolean[] edgeFlagArray, Matrix[] transform) { if (globe == null) { String message = Logging.getMessage("nullValue.GlobeIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (locations == null) { String message = "nullValue.LocationsIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (points == null) { String message = "nullValue.LocationsIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (points.length < (1 + locations.size())) { String message = Logging.getMessage( "generic.ArrayInvalidLength", "points.length < " + (1 + locations.size())); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (transform == null) { String message = "nullValue.TransformIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (transform.length < 1) { String message = Logging.getMessage("generic.ArrayInvalidLength", "transform.length < 1"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Allocate space to hold the list of locations and location vertices. int locationCount = locations.size(); // Compute the cartesian points for each location. for (int i = 0; i < locationCount; i++) { LatLon ll = locations.get(i); points[i] = globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(), 0.0); if (edgeFlagArray != null) edgeFlagArray[i] = (edgeFlags != null) ? edgeFlags.get(i) : true; } // Compute the average of the cartesian points. Vec4 centerPoint = Vec4.computeAveragePoint(Arrays.asList(points)); // Test whether the polygon is closed. If it is not closed, repeat the first vertex. if (!points[0].equals(points[locationCount - 1])) { points[locationCount] = points[0]; if (edgeFlagArray != null) edgeFlagArray[locationCount] = edgeFlagArray[0]; locationCount++; } // Compute a transform that will map the cartesian points to a local coordinate system centered // at the average // of the points and oriented with the globe surface. Position centerPos = globe.computePositionFromPoint(centerPoint); Matrix tx = globe.computeSurfaceOrientationAtPosition(centerPos); Matrix txInv = tx.getInverse(); // Map the cartesian points to a local coordinate space. for (int i = 0; i < locationCount; i++) { points[i] = points[i].transformBy4(txInv); } transform[0] = tx; return locationCount; }
/** * Indicates the transform matrix applied to this document. * * @return Transform matrix. */ protected Matrix getMatrix() { // If the matrix has already been computed then just return the cached value. if (this.matrix != null) return this.matrix; Matrix m = Matrix.IDENTITY; if (this.heading != null) m = m.multiply(Matrix.fromRotationZ(Angle.POS360.subtract(this.heading))); if (this.pitch != null) m = m.multiply(Matrix.fromRotationX(this.pitch)); if (this.roll != null) m = m.multiply(Matrix.fromRotationY(this.roll)); // Apply scaling factor to convert file units to meters. double scale = this.getScale(); m = m.multiply(Matrix.fromScale(scale)); if (this.modelScale != null) m = m.multiply(Matrix.fromScale(this.modelScale)); this.matrix = m; return m; }