001 package com.croftsoft.core.media.j3d; 002 003 import java.awt.event.KeyEvent; 004 005 import javax.media.j3d.*; 006 import javax.vecmath.*; 007 008 /********************************************************************* 009 * 010 * Static method library to manipulate Transform3D data. 011 * Primarily focuses on transforming a view through the 6 degrees of 012 * freedom. 013 * 014 * <P> 015 * 016 * <B>Reference:</B> 017 * <P> 018 * 019 * Foley, et al., <U>Computer Graphics: Principles and Practice</U>. 020 * Provides the mathematics for the 3D rotation matrices. 021 * 022 * @author 023 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 024 * @version 025 * 1998-12-06 026 *********************************************************************/ 027 028 public class Transform3DLib 029 ////////////////////////////////////////////////////////////////////// 030 ////////////////////////////////////////////////////////////////////// 031 { 032 033 /** Relative X axis */ 034 public static final int X = 0; 035 036 /** Relative Y axis */ 037 public static final int Y = 1; 038 039 /** Relative Z axis */ 040 public static final int Z = 2; 041 042 private Transform3DLib ( ) { /* empty */ } 043 044 ////////////////////////////////////////////////////////////////////// 045 ////////////////////////////////////////////////////////////////////// 046 047 /********************************************************************* 048 * Rotates the view by the given rotation matrix. 049 * 050 * @param transform3D 051 * The transform containing the current rotation matrix. 052 * @param rotation 053 * The rotation matrix to be muliplied. 054 * @return 055 * The transform3D argument has its current rotation matrix replaced 056 * by its old value as multiplied by the rotation argument. 057 *********************************************************************/ 058 public static void viewRotate ( 059 Transform3D transform3D, Matrix3d rotation ) 060 ////////////////////////////////////////////////////////////////////// 061 { 062 Matrix3d oldRotation = new Matrix3d ( ); 063 transform3D.get ( oldRotation ); 064 oldRotation.mul ( rotation ); 065 transform3D.setRotation ( oldRotation ); 066 } 067 068 /********************************************************************* 069 * Pitches the view by a given number of radians. 070 * 071 * @param transform3D 072 * The transform containing the current rotation matrix. 073 * @param radians 074 * The angle to rotate the transform about its relative X axis. 075 * @return 076 * The rotation matrix is updated in the transform3D argument. 077 *********************************************************************/ 078 public static void viewPitch ( 079 Transform3D transform3D, double radians ) 080 ////////////////////////////////////////////////////////////////////// 081 { 082 double sin = Math.sin ( radians ); 083 double cos = Math.cos ( radians ); 084 085 viewRotate ( transform3D, new Matrix3d ( 086 1.0, 0.0, 0.0, 087 0.0, cos, -sin, 088 0.0, sin, cos ) ); 089 } 090 091 /********************************************************************* 092 * Yaws the view by a given number of radians. 093 * 094 * @param transform3D 095 * The transform containing the current rotation matrix. 096 * @param radians 097 * The angle to rotate the transform about its relative Y axis. 098 * @return 099 * The rotation matrix is updated in the transform3D argument. 100 *********************************************************************/ 101 public static void viewYaw ( 102 Transform3D transform3D, double radians ) 103 ////////////////////////////////////////////////////////////////////// 104 { 105 double sin = Math.sin ( radians ); 106 double cos = Math.cos ( radians ); 107 108 viewRotate ( transform3D, new Matrix3d ( 109 cos, 0.0, sin, 110 0.0, 1.0, 0.0, 111 -sin, 0.0, cos ) ); 112 } 113 114 /********************************************************************* 115 * Rolls the view by a given number of radians. 116 * 117 * @param transform3D 118 * The transform containing the current rotation matrix. 119 * @param radians 120 * The angle to rotate the transform about its relative Z axis. 121 * @return 122 * The rotation matrix is updated in the transform3D argument. 123 *********************************************************************/ 124 public static void viewRoll ( 125 Transform3D transform3D, double radians ) 126 ////////////////////////////////////////////////////////////////////// 127 { 128 double sin = Math.sin ( radians ); 129 double cos = Math.cos ( radians ); 130 131 viewRotate ( transform3D, new Matrix3d ( 132 cos, -sin, 0.0, 133 sin, cos, 0.0, 134 0.0, 0.0, 1.0 ) ); 135 } 136 137 /********************************************************************* 138 * Translates the view by a given distance along a relative axis. 139 * 140 * @param transform3D 141 * The transform containing the current rotation and translation 142 * matrix. 143 * @param dimension 144 * The relative axis to translate along. 145 * Use the public constants X, Y, and Z provided by this class. 146 * @return 147 * The translation vector is updated in the transform3D argument. 148 *********************************************************************/ 149 public static void viewTranslate ( 150 Transform3D transform3D, 151 int dimension, 152 double distance ) 153 ////////////////////////////////////////////////////////////////////// 154 { 155 Matrix3d rotation = new Matrix3d ( ); 156 Vector3d translation = new Vector3d ( ); 157 transform3D.get ( rotation, translation ); 158 159 // Get the alignment of the rotated relative axes. 160 Vector3d r = new Vector3d ( ); 161 rotation.getColumn ( dimension, r ); 162 163 r.scale ( distance ); 164 165 translation.add ( r ); 166 167 transform3D.setTranslation ( translation ); 168 } 169 170 /********************************************************************* 171 * Transforms the view based upon a user keyboard input. 172 * 173 * @param transform3D 174 * The transform containing the current rotation and translation 175 * matrices, usually the user's view transform. 176 * @param keyEvent 177 * Arrow keys in combination with no other key, the Shift key, or 178 * the Alt key will rotate or translate the transform about the 179 * relative X, Y, and Z axes respectively for 6 degrees of freedom. 180 * @param deltaRotation 181 * The number of radians to rotate the view upon a keyboard input. 182 * @param deltaTranslation 183 * The distance to translate the view upon a keyboard input. 184 * @return 185 * Returns true if any changes were made to transform3D argument. 186 *********************************************************************/ 187 public static boolean viewKeyPressed ( 188 Transform3D transform3D, 189 KeyEvent keyEvent, 190 double deltaRotation, 191 double deltaTranslation ) 192 ////////////////////////////////////////////////////////////////////// 193 { 194 boolean moved = false; 195 196 int keyCode = keyEvent.getKeyCode ( ); 197 198 if ( keyEvent.isAltDown ( ) ) 199 { 200 switch ( keyCode ) 201 { 202 case KeyEvent.VK_UP : 203 viewTranslate ( transform3D, Z, -deltaTranslation ); 204 moved = true; 205 break; 206 case KeyEvent.VK_DOWN : 207 viewTranslate ( transform3D, Z, deltaTranslation ); 208 moved = true; 209 break; 210 case KeyEvent.VK_LEFT : 211 viewRoll ( transform3D, deltaRotation ); 212 moved = true; 213 break; 214 case KeyEvent.VK_RIGHT: 215 viewRoll ( transform3D, -deltaRotation ); 216 moved = true; 217 break; 218 } 219 } 220 else if ( keyEvent.isShiftDown ( ) ) 221 { 222 switch ( keyCode ) 223 { 224 case KeyEvent.VK_UP : 225 viewTranslate ( 226 transform3D, Y, deltaTranslation ); 227 moved = true; 228 break; 229 case KeyEvent.VK_DOWN : 230 viewTranslate ( 231 transform3D, Y, -deltaTranslation ); 232 moved = true; 233 break; 234 case KeyEvent.VK_LEFT : 235 viewYaw ( transform3D, deltaRotation ); 236 moved = true; 237 break; 238 case KeyEvent.VK_RIGHT: 239 viewYaw ( transform3D, -deltaRotation ); 240 moved = true; 241 break; 242 } 243 } 244 else 245 { 246 switch ( keyCode ) 247 { 248 case KeyEvent.VK_UP : 249 viewPitch ( transform3D, -deltaRotation ); 250 moved = true; 251 break; 252 case KeyEvent.VK_DOWN : 253 viewPitch ( transform3D, deltaRotation ); 254 moved = true; 255 break; 256 case KeyEvent.VK_LEFT : 257 viewTranslate ( 258 transform3D, X, -deltaTranslation ); 259 moved = true; 260 break; 261 case KeyEvent.VK_RIGHT: 262 viewTranslate ( 263 transform3D, X, deltaTranslation ); 264 moved = true; 265 break; 266 } 267 } 268 269 return moved; 270 } 271 272 ////////////////////////////////////////////////////////////////////// 273 ////////////////////////////////////////////////////////////////////// 274 }