2 Copyright (C) 2001, 2006 United States Government as represented by
3 the Administrator of the National Aeronautics and Space Administration.
6 package gov
.nasa
.worldwind
.view
;
8 import gov
.nasa
.worldwind
.geom
.*;
9 import gov
.nasa
.worldwind
.globes
.Globe
;
10 import gov
.nasa
.worldwind
.render
.DrawContext
;
11 import gov
.nasa
.worldwind
.util
.Logging
;
15 * @version $Id: OrbitViewModel.java 2503 2007-08-03 23:22:10Z dcollins $
19 private Matrix transformMatrix
= null;
21 public OrbitViewModel(DrawContext dc
)
23 this(dc
, Angle
.ZERO
, Angle
.ZERO
, Angle
.ZERO
, Angle
.ZERO
, 0);
26 public OrbitViewModel(DrawContext dc
,
27 Angle latitude
, Angle longitude
,
28 Angle heading
, Angle pitch
,
31 this(dc
, createInitTransform(
38 public OrbitViewModel(DrawContext dc
, Matrix transformMatrix
)
42 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
43 Logging
.logger().severe(message
);
44 throw new IllegalArgumentException(message
);
46 if (transformMatrix
== null)
48 String message
= Logging
.getMessage("nullValue.MatrixIsNull");
49 Logging
.logger().severe(message
);
50 throw new IllegalArgumentException(message
);
53 this.setTransform(dc
, transformMatrix
);
56 public Matrix
getTransformMatrix()
58 return this.transformMatrix
;
61 private void onTransformChange(DrawContext dc
, Matrix newTransformMatrix
)
65 public void setTransform(DrawContext dc
, Matrix newTransformMatrix
)
69 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
70 Logging
.logger().severe(message
);
71 throw new IllegalArgumentException(message
);
73 if (newTransformMatrix
== null)
75 String message
= Logging
.getMessage("nullValue.MatrixIsNull");
76 Logging
.logger().severe(message
);
77 throw new IllegalArgumentException(message
);
80 this.transformMatrix
= newTransformMatrix
;
81 this.onTransformChange(dc
, newTransformMatrix
);
84 public void transform(DrawContext dc
, Matrix transformMatrix
)
88 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
89 Logging
.logger().severe(message
);
90 throw new IllegalArgumentException(message
);
92 if (transformMatrix
== null)
94 String message
= Logging
.getMessage("nullValue.MatrixIsNull");
95 Logging
.logger().severe(message
);
96 throw new IllegalArgumentException(message
);
99 if (this.transformMatrix
== null)
102 Matrix newTransformMatrix
= this.transformMatrix
.multiply(transformMatrix
);
103 this.setTransform(dc
, newTransformMatrix
);
106 public void transformLatitude(DrawContext dc
, Angle amount
)
110 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
111 Logging
.logger().severe(message
);
112 throw new IllegalArgumentException(message
);
116 String message
= Logging
.getMessage("nullValue.AngleIsNull");
117 Logging
.logger().severe(message
);
118 throw new IllegalArgumentException(message
);
121 Matrix latTransform
= this.createLatitudeTransform(dc
, amount
);
122 if (latTransform
== null)
125 if (this.transformMatrix
== null)
128 // Test transform application.
129 Matrix newTransformMatrix
= this.transformMatrix
.multiply(latTransform
);
130 Vec4 center
= computeLookAtPoint(dc
, this.transformMatrix
);
131 Vec4 newCenter
= computeLookAtPoint(dc
, newTransformMatrix
);
132 Position centerPos
= dc
.getGlobe().computePositionFromPoint(center
);
133 Position newCenterPos
= dc
.getGlobe().computePositionFromPoint(newCenter
);
134 // Abort the transform when it causes model errors.
135 final double EPSILON
= 1e-10;
136 if (Math
.abs(newCenterPos
.getLongitude().subtract(centerPos
.getLongitude()).degrees
) > EPSILON
)
139 this.transform(dc
, latTransform
);
142 public void transformLongitude(DrawContext dc
, Angle amount
)
146 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
147 Logging
.logger().severe(message
);
148 throw new IllegalArgumentException(message
);
152 String message
= Logging
.getMessage("nullValue.AngleIsNull");
153 Logging
.logger().severe(message
);
154 throw new IllegalArgumentException(message
);
157 Matrix lonTransform
= this.createLongitudeTransform(dc
, amount
);
158 if (lonTransform
== null)
161 this.transform(dc
, lonTransform
);
164 public void transformAltitude(DrawContext dc
, double amount
)
168 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
169 Logging
.logger().severe(message
);
170 throw new IllegalArgumentException(message
);
173 Matrix altTransform
= this.createAltitudeTransform(dc
, amount
);
174 if (altTransform
== null)
177 this.transform(dc
, altTransform
);
180 public void transformHeading(DrawContext dc
, Angle amount
)
184 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
185 Logging
.logger().severe(message
);
186 throw new IllegalArgumentException(message
);
190 String message
= Logging
.getMessage("nullValue.AngleIsNull");
191 Logging
.logger().severe(message
);
192 throw new IllegalArgumentException(message
);
195 Matrix headingTransform
= this.createHeadingTransform(dc
, amount
);
196 if (headingTransform
== null)
199 this.transform(dc
, headingTransform
);
202 public void transformPitch(DrawContext dc
, Angle amount
)
206 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
207 Logging
.logger().severe(message
);
208 throw new IllegalArgumentException(message
);
212 String message
= Logging
.getMessage("nullValue.AngleIsNull");
213 Logging
.logger().severe(message
);
214 throw new IllegalArgumentException(message
);
217 Matrix pitchTransform
= this.createPitchTransform(dc
, amount
);
218 if (pitchTransform
== null)
221 if (this.transformMatrix
== null)
224 // Test transform application.
225 Matrix newTransformMatrix
= this.transformMatrix
.multiply(pitchTransform
);
226 Vec4 centerVec
= computeLookAtPoint(dc
, this.transformMatrix
);
227 Vec4 newHeading
= computeHeadingVector(newTransformMatrix
, centerVec
);
228 Vec4 newForward
= Vec4
.UNIT_NEGATIVE_Z
.transformBy3(newTransformMatrix
.getInverse());
229 // Abort the transform when it causes model errors.
230 if (newHeading
.dot3(newForward
) < 0)
233 this.transform(dc
, pitchTransform
);
236 public void transformZoom(DrawContext dc
, double amount
)
240 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
241 Logging
.logger().severe(message
);
242 throw new IllegalArgumentException(message
);
245 Matrix zoomTransform
= this.createZoomTransform(dc
, amount
);
246 if (zoomTransform
== null)
249 this.transform(dc
, zoomTransform
);
252 public Quaternion
getRotation()
254 return Quaternion
.fromMatrix(this.transformMatrix
);
257 public void setRotation(DrawContext dc
, Quaternion newRotation
)
261 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
262 Logging
.logger().severe(message
);
263 throw new IllegalArgumentException(message
);
265 if (newRotation
== null)
267 String message
= Logging
.getMessage("nullValue.QuaternionIsNull");
268 Logging
.logger().severe(message
);
269 throw new IllegalArgumentException(message
);
272 if (this.transformMatrix
== null)
275 Matrix posMatrix
= Matrix
.fromTranslation(
276 this.transformMatrix
.m14
,
277 this.transformMatrix
.m24
,
278 this.transformMatrix
.m34
);
279 Matrix rotMatrix
= Matrix
.fromQuaternion(newRotation
);
280 Matrix newTransformMatrix
= posMatrix
.multiply(rotMatrix
);
281 this.setTransform(dc
, newTransformMatrix
);
284 public void transformRotation(DrawContext dc
, Quaternion rotation
)
288 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
289 Logging
.logger().severe(message
);
290 throw new IllegalArgumentException(message
);
292 if (rotation
== null)
294 String message
= Logging
.getMessage("nullValue.QuaternionIsNull");
295 Logging
.logger().severe(message
);
296 throw new IllegalArgumentException(message
);
299 Quaternion transformRotation
= Quaternion
.fromMatrix(this.transformMatrix
);
300 Quaternion newTransformRotation
= transformRotation
.multiply(rotation
);
301 this.setRotation(dc
, newTransformRotation
);
304 // ============== Model Transforms ======================= //
305 // ============== Model Transforms ======================= //
306 // ============== Model Transforms ======================= //
308 private static Matrix
createInitTransform(
310 Angle latitude
, Angle longitude
,
311 Angle heading
, Angle pitch
,
315 || dc
.getGlobe() == null
322 Globe globe
= dc
.getGlobe();
323 // Vec4 globeOrigin = globe.getCenter();
324 Matrix initTransform
= Matrix
.IDENTITY
;
325 // Not sure why this isn't necessary, but when globeOrigin!=0 View is still centered on the Globe,
326 // without this code.
327 // initTransform = initTransform.multiply(Matrix.fromTranslation(
331 initTransform
= initTransform
.multiply(Matrix
.fromTranslation(
334 0.0 - globe
.getRadiusAt(latitude
, longitude
)));
335 initTransform
= initTransform
.multiply(Matrix
.fromRotationX(heading
.multiply(-1)));
336 initTransform
= initTransform
.multiply(Matrix
.fromRotationZ(pitch
));
337 initTransform
= initTransform
.multiply(Matrix
.fromTranslation(
341 initTransform
= initTransform
.multiply(Matrix
.fromRotationX(latitude
));
342 initTransform
= initTransform
.multiply(Matrix
.fromRotationY(longitude
.multiply(-1)));
344 return initTransform
;
347 public Matrix
createLatitudeTransform(DrawContext dc
, Angle amount
)
351 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
352 Logging
.logger().severe(message
);
353 throw new IllegalArgumentException(message
);
357 String message
= Logging
.getMessage("nullValue.AngleIsNull");
358 Logging
.logger().severe(message
);
359 throw new IllegalArgumentException(message
);
362 Vec4 centerVec
= this.getLookAtVector(dc
);
363 if (centerVec
== null)
366 Vec4 surfaceNormal
= centerVec
.normalize3();
367 Vec4 axis
= Vec4
.UNIT_Y
.cross3(surfaceNormal
);
368 return Matrix
.fromAxisAngle(amount
, axis
);
371 public Matrix
createLongitudeTransform(DrawContext dc
, Angle amount
)
375 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
376 Logging
.logger().severe(message
);
377 throw new IllegalArgumentException(message
);
381 String message
= Logging
.getMessage("nullValue.AngleIsNull");
382 Logging
.logger().severe(message
);
383 throw new IllegalArgumentException(message
);
386 Vec4 axis
= Vec4
.UNIT_Y
;
387 return Matrix
.fromAxisAngle(amount
.multiply(-1), axis
);
390 public Matrix
createAltitudeTransform(DrawContext dc
, double amount
)
394 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
395 Logging
.logger().severe(message
);
396 throw new IllegalArgumentException(message
);
399 Vec4 altVec
= this.getEyeVector();
403 altVec
= altVec
.normalize3();
404 altVec
= altVec
.multiply3(-amount
);
405 return Matrix
.fromTranslation(altVec
);
408 public Matrix
createHeadingTransform(DrawContext dc
, Angle amount
)
412 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
413 Logging
.logger().severe(message
);
414 throw new IllegalArgumentException(message
);
418 String message
= Logging
.getMessage("nullValue.AngleIsNull");
419 Logging
.logger().severe(message
);
420 throw new IllegalArgumentException(message
);
423 Vec4 centerVec
= this.getLookAtVector(dc
);
424 if (centerVec
== null)
427 Vec4 axis
= centerVec
.normalize3();
428 Matrix axisAngleTransform
= Matrix
.fromAxisAngle(amount
, axis
);
429 return this.createTransformAboutPivot(axisAngleTransform
, centerVec
);
432 public Matrix
createPitchTransform(DrawContext dc
, Angle amount
)
436 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
437 Logging
.logger().severe(message
);
438 throw new IllegalArgumentException(message
);
442 String message
= Logging
.getMessage("nullValue.AngleIsNull");
443 Logging
.logger().severe(message
);
444 throw new IllegalArgumentException(message
);
447 if (this.transformMatrix
== null)
450 Vec4 centerVec
= this.getLookAtVector(dc
);
451 if (centerVec
== null)
454 Vec4 axis
= Vec4
.UNIT_X
.transformBy3(this.transformMatrix
.getInverse());
455 Matrix axisAngleTransform
= Matrix
.fromAxisAngle(amount
.multiply(-1), axis
);
456 return this.createTransformAboutPivot(axisAngleTransform
, centerVec
);
459 public Matrix
createZoomTransform(DrawContext dc
, double amount
)
463 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
464 Logging
.logger().severe(message
);
465 throw new IllegalArgumentException(message
);
468 if (this.transformMatrix
== null)
471 Vec4 zoomVec
= Vec4
.UNIT_NEGATIVE_Z
.transformBy3(this.transformMatrix
.getInverse());
472 zoomVec
= zoomVec
.normalize3();
473 zoomVec
= zoomVec
.multiply3(amount
);
474 return Matrix
.fromTranslation(zoomVec
);
477 private Matrix
createTransformAboutPivot(Matrix transform
, Vec4 pivot
)
479 if (transform
== null || pivot
== null)
482 Matrix matrix
= Matrix
.IDENTITY
;
483 matrix
= matrix
.multiply(Matrix
.fromTranslation(pivot
.x
, pivot
.y
, pivot
.z
));
484 matrix
= matrix
.multiply(transform
);
485 matrix
= matrix
.multiply(Matrix
.fromTranslation(-pivot
.x
, -pivot
.y
, -pivot
.z
));
489 // ============== Rotation Transforms ======================= //
490 // ============== Rotation Transforms ======================= //
491 // ============== Rotation Transforms ======================= //
493 public Quaternion
createRotationBetweenPositions(DrawContext dc
, Position beginPosition
, Position endPosition
)
497 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
498 Logging
.logger().severe(message
);
499 throw new IllegalArgumentException(message
);
501 if (beginPosition
== null || endPosition
== null)
503 String message
= Logging
.getMessage("nullValue.PositionIsNull");
504 Logging
.logger().severe(message
);
505 throw new IllegalArgumentException(message
);
508 Globe globe
= dc
.getGlobe();
512 Vec4 beginPoint
= globe
.computePointFromPosition(beginPosition
);
513 Vec4 endPoint
= globe
.computePointFromPosition(endPosition
);
514 if (beginPoint
== null || endPoint
== null)
517 Angle angle
= beginPoint
.angleBetween3(endPoint
);
521 Vec4 axis
= beginPoint
.cross3(endPoint
);
522 return Quaternion
.fromAxisAngle(angle
, axis
);
525 public Quaternion
createRotationForward(DrawContext dc
, Angle amount
)
529 String message
= Logging
.getMessage("nullValue.AngleIsNull");
530 Logging
.logger().severe(message
);
531 throw new IllegalArgumentException(message
);
534 if (this.transformMatrix
== null)
537 Vec4 xAxis
= Vec4
.UNIT_X
.transformBy3(this.transformMatrix
.getInverse());
538 return Quaternion
.fromAxisAngle(amount
, xAxis
);
541 public Quaternion
createRotationRight(DrawContext dc
, Angle amount
)
545 String message
= Logging
.getMessage("nullValue.AngleIsNull");
546 Logging
.logger().severe(message
);
547 throw new IllegalArgumentException(message
);
550 if (this.transformMatrix
== null)
553 Vec4 xAxis
= Vec4
.UNIT_X
.transformBy3(this.transformMatrix
.getInverse());
554 Vec4 centerVec
= this.getLookAtVector(dc
);
555 centerVec
= centerVec
.normalize3();
556 Vec4 yAxisNoTilt
= centerVec
.cross3(xAxis
);
557 return Quaternion
.fromAxisAngle(amount
.multiply(-1), yAxisNoTilt
);
560 // ============== Viewing Attributes ======================= //
561 // ============== Viewing Attributes ======================= //
562 // ============== Viewing Attributes ======================= //
564 public Vec4
getEyeVector()
566 if (this.transformMatrix
== null)
569 return Vec4
.UNIT_W
.transformBy4(this.transformMatrix
.getInverse());
572 public Position
getEyePosition(DrawContext dc
)
576 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
577 Logging
.logger().severe(message
);
578 throw new IllegalArgumentException(message
);
581 Vec4 eyeVec
= this.getEyeVector();
585 if (dc
.getGlobe() == null)
588 return dc
.getGlobe().computePositionFromPoint(eyeVec
);
591 public Vec4
getLookAtVector(DrawContext dc
)
595 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
596 Logging
.logger().severe(message
);
597 throw new IllegalArgumentException(message
);
600 if (this.transformMatrix
== null)
603 return computeLookAtPoint(dc
, this.transformMatrix
);
606 public Position
getLookAtPosition(DrawContext dc
)
610 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
611 Logging
.logger().severe(message
);
612 throw new IllegalArgumentException(message
);
615 Vec4 centerVec
= this.getLookAtVector(dc
);
616 if (centerVec
== null)
619 if (dc
.getGlobe() == null)
622 return dc
.getGlobe().computePositionFromPoint(centerVec
);
625 public Angle
getHeading(DrawContext dc
)
629 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
630 Logging
.logger().severe(message
);
631 throw new IllegalArgumentException(message
);
634 if (this.transformMatrix
== null)
637 Vec4 centerVec
= this.getLookAtVector(dc
);
638 if (centerVec
== null)
641 HeadingCoordinates headingCoordinates
= computeHeadingCoordinates(centerVec
);
642 if (headingCoordinates
== null)
645 return computeHeading(headingCoordinates
, this.transformMatrix
, centerVec
);
648 public Angle
getPitch(DrawContext dc
)
652 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
653 Logging
.logger().severe(message
);
654 throw new IllegalArgumentException(message
);
657 if (this.transformMatrix
== null)
660 Vec4 centerVec
= this.getLookAtVector(dc
);
661 if (centerVec
== null)
664 return computePitch(this.transformMatrix
, centerVec
);
667 public Double
getZoom(DrawContext dc
)
671 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
672 Logging
.logger().severe(message
);
673 throw new IllegalArgumentException(message
);
676 if (this.transformMatrix
== null)
679 Vec4 centerVec
= this.getLookAtVector(dc
);
680 if (centerVec
== null)
683 return computeZoom(this.transformMatrix
, centerVec
);
686 // ============== Attribute Computation Support ======================= //
687 // ============== Attribute Computation Support ======================= //
688 // ============== Attribute Computation Support ======================= //
690 private static Vec4
computeLookAtPoint(DrawContext dc
, Matrix transformMatrix
)
693 || dc
.getGlobe() == null
694 || transformMatrix
== null)
697 Globe globe
= dc
.getGlobe();
698 Vec4 eyeVec
= Vec4
.UNIT_W
.transformBy4(transformMatrix
.getInverse());
699 Vec4 forwardVec
= Vec4
.UNIT_NEGATIVE_Z
.transformBy3(transformMatrix
.getInverse());
700 forwardVec
= forwardVec
.normalize3();
702 Position centerPos
= globe
.getIntersectionPosition(new Line(eyeVec
, forwardVec
));
703 if (centerPos
== null)
704 return computeHorizonPoint(globe
, transformMatrix
);
706 Angle centerLat
= centerPos
.getLatitude();
707 Angle centerLon
= centerPos
.getLongitude();
708 double centerElevation
= dc
.getVerticalExaggeration() * globe
.getElevation(centerLat
, centerLon
);
709 return globe
.computePointFromPosition(centerLat
, centerLon
, centerElevation
);
712 private static Vec4
computeHorizonPoint(Globe globe
, Matrix transformMatrix
)
714 if (globe
== null || transformMatrix
== null)
717 Vec4 globeOrigin
= globe
.getCenter();
718 Vec4 eyeVec
= Vec4
.UNIT_W
.transformBy4(transformMatrix
.getInverse());
719 Vec4 forward
= Vec4
.UNIT_NEGATIVE_Z
.transformBy3(transformMatrix
.getInverse());
720 Vec4 origin_sub_eye
= globeOrigin
.subtract3(eyeVec
);
722 double r
= globe
.getRadius();
723 double dSquared
= origin_sub_eye
.getLengthSquared3() - (r
* r
);
727 double d
= Math
.sqrt(dSquared
);
728 return forward
.normalize3().multiply3(d
).add3(eyeVec
);
731 private static Angle
computeHeading(HeadingCoordinates headingCoords
, Matrix transformMatrix
, Vec4 lookAtPoint
)
733 if (headingCoords
== null
734 || transformMatrix
== null
735 || lookAtPoint
== null)
738 Vec4 heading
= computeHeadingVector(transformMatrix
, lookAtPoint
);
740 double dot
= headingCoords
.north
.dot3(heading
);
741 // Compute the sum of magnitudes.
742 double length
= headingCoords
.north
.getLength3() * heading
.getLength3();
743 // Normalize the dot product, if necessary.
744 if ((length
!= 0) && (length
!= 1.0))
747 if (dot
< -1) // Angle is positive 180.
751 else if (dot
> 1) // Angle is zero.
756 double degrees
= Math
.toDegrees(Math
.acos(dot
));
757 if (Double
.isNaN(degrees
))
760 if (headingCoords
.east
.dot3(heading
) < 0)
761 degrees
= 360 - degrees
;
763 // Collapses duplicate values for North heading.
767 return Angle
.fromDegrees(degrees
);
770 private static class HeadingCoordinates
772 public final Vec4 north
;
773 public final Vec4 east
;
775 public HeadingCoordinates(Vec4 north
, Vec4 east
)
782 private static HeadingCoordinates
computeHeadingCoordinates(Vec4 lookAtPoint
)
784 if (lookAtPoint
== null)
787 Vec4 surfaceNormal
= lookAtPoint
.normalize3();
788 Vec4 y_sub_normal
= Vec4
.UNIT_Y
.subtract3(surfaceNormal
);
789 y_sub_normal
= y_sub_normal
.normalize3();
790 Vec4 eastVec
= y_sub_normal
.cross3(surfaceNormal
);
791 Vec4 northVec
= surfaceNormal
.cross3(eastVec
);
792 eastVec
= northVec
.cross3(surfaceNormal
);
794 return new HeadingCoordinates(northVec
, eastVec
);
797 private static Vec4
computeHeadingVector(Matrix transformMatrix
, Vec4 surfacePoint
)
799 if (transformMatrix
== null || surfacePoint
== null)
802 Vec4 surfaceNormal
= surfacePoint
.normalize3();
803 Vec4 forward
= Vec4
.UNIT_NEGATIVE_Z
.transformBy3(transformMatrix
.getInverse());
804 Vec4 up
= Vec4
.UNIT_Y
.transformBy3(transformMatrix
.getInverse());
806 final double EPSILON
= 0.1;
807 Vec4 heading
= forward
.cross3(surfaceNormal
);
808 if (heading
.getLength3() < EPSILON
)
809 heading
= up
.cross3(surfaceNormal
);
810 heading
= surfaceNormal
.cross3(heading
);
811 heading
= heading
.normalize3();
816 private static Angle
computePitch(Matrix transformMatrix
, Vec4 lookAtPoint
)
818 if (transformMatrix
== null || lookAtPoint
== null)
821 Vec4 surfaceNormal
= lookAtPoint
.normalize3();
822 Vec4 forward
= Vec4
.UNIT_Z
.transformBy3(transformMatrix
.getInverse());
823 forward
= forward
.normalize3();
825 double dot
= surfaceNormal
.dot3(forward
);
826 // Compute the sum of magnitudes.
827 double length
= surfaceNormal
.getLength3() * forward
.getLength3();
828 // Normalize the dot product, if necessary.
829 if ((length
!= 0) && (length
!= 1))
832 if (dot
<= 0) // Angle is positive 90.
836 else if (dot
>= 1) // Angle is zero.
840 else // Angle is arc-cosine of dot product.
842 double radians
= Math
.acos(dot
);
843 if (!Double
.isNaN(radians
))
844 return Angle
.fromRadians(radians
);
850 private static Double
computeZoom(Matrix transformMatrix
, Vec4 lookAtPoint
)
852 if (transformMatrix
== null || lookAtPoint
== null)
855 Vec4 eyeVec
= Vec4
.UNIT_W
.transformBy4(transformMatrix
.getInverse());
856 return lookAtPoint
.subtract3(eyeVec
).getLength3();
859 // private static class SurfaceAttributes
861 // public final Vec4 center;
862 // public final Position centerPos;
863 // public final Vec4 north;
864 // public final Vec4 east;
866 // public SurfaceAttributes(Vec4 centerVec, Position centerPos, Vec4 headingUp, Vec4 headingRight)
868 // this.center = centerVec;
869 // this.centerPos = centerPos;
870 // this.north = headingUp;
871 // this.east = headingRight;
875 // private static SurfaceAttributes computeSurfaceAttributes(DrawContext dc, Matrix transformMatrix)
877 // if (dc == null || dc.getGlobe() == null)
880 // if (transformMatrix == null)
883 // Globe globe = dc.getGlobe();
884 // Vec4 eyeVec = Vec4.UNIT_W.transformBy4(transformMatrix.getInverse());
885 // Vec4 forwardVec = Vec4.UNIT_NEGATIVE_Z.transformBy3(transformMatrix.getInverse());
886 // forwardVec = forwardVec.normalize3();
889 // Position centerPos = globe.getIntersectionPosition(new Line(eyeVec, forwardVec));
890 // if (centerPos != null)
892 // Angle centerLat = centerPos.getLatitude();
893 // Angle centerLon = centerPos.getLongitude();
894 // double centerElevation = dc.getVerticalExaggeration() * globe.getElevation(centerLat, centerLon);
895 // centerVec = globe.computePointFromPosition(centerLat, centerLon, centerElevation);
899 // centerVec = computeHorizonPoint(globe, transformMatrix);
900 // centerPos = globe.computePositionFromPoint(centerVec);
903 // if (centerVec == null)
906 // Vec4 normalVec = centerVec.normalize3();
908 // Vec4 y_sub_normal = Vec4.UNIT_Y.subtract3(normalVec);
909 // y_sub_normal = y_sub_normal.normalize3();
910 // Vec4 headingRight = y_sub_normal.cross3(normalVec);
911 // Vec4 headingUp = normalVec.cross3(headingRight);
912 // headingRight = headingUp.cross3(normalVec);
914 // return new SurfaceAttributes(centerVec, centerPos, headingUp.normalize3(), headingRight.normalize3());