View Javadoc

1   package com.insanityengine.ghia.m3;
2   
3   /***
4    *
5    * <P>
6    * Big fat thanks to:
7    * </P>
8    *
9    * <UL>
10   *	<LI>http://www.gamasutra.com/features/19980703/quaternions_01.htm</LI>
11   *  <LI>http://www.macromedia.com/devnet/mx/flash/articles/3d_classes_04.html</LI>
12   *	<LI>http://graphics.stanford.edu/courses/cs348c-95-fall/software/quatdemo/</LI>
13   *	<LI>http://personal.nbnet.nb.ca/daveg/opengl/</LI>
14   * </UL>
15   *
16   * <P>
17   * Their usefulness is due in no small measure to the code artifacts they supplied...
18   * Two lines of code can be more useful than 2 pages of text.
19   * </P>
20   *
21   * <P>
22   * Here are some that seemed useful, but confused me:
23   * </P>
24   *
25   * <UL>
26   *	<LI>http://www.sjbrown.co.uk/quaternions.html</LI>
27   *	<LI></LI>
28   * </UL>
29   *
30   * <P>
31   * Sadly, it's just still not workin'!
32   * </P>
33   *
34   * @author BrianHammond
35   *
36   * $Header: /usr/local/cvsroot/ghia/src/java/com/insanityengine/ghia/m3/Quat.java,v 1.4 2005/03/19 17:50:02 brian Exp $
37   *
38   */
39  public class Quat {
40  
41  	/*** 
42  	 * 
43  	 * Constructor
44  	 * 
45  	 */
46  	public Quat() {
47  		set( 0 );
48  	}
49  
50  	/*** 
51  	 * 
52  	 * Constructor
53  	 * 
54  	 * @param x
55  	 * @param y
56  	 * @param z
57  	 * 
58  	 */
59  	public Quat( float x, float y, float z ) {
60  		set( x, y, z );
61  	}
62  
63  	/*** 
64  	 * 
65  	 * Constructor
66  	 * 
67  	 * @param x
68  	 * @param y
69  	 * @param z
70  	 * @param w
71  	 * 
72  	 */
73  	public Quat( float x, float y, float z, float w ) {
74  		set( x, y, z, w );
75  	}
76  
77  	/*** 
78  	 * 
79  	 * Constructor
80  	 * 
81  	 * @param point
82  	 * 
83  	 */
84  	public Quat( Pt3 point ) {
85  		set( point );
86  	}
87  
88  	/*** 
89  	 * 
90  	 * Constructor
91  	 * 
92  	 * @param that
93  	 * 
94  	 */
95  	public Quat( Quat that ) {
96  		set( that );
97  	}
98  
99  	/*** 
100 	 * 
101 	 * set
102 	 * 
103 	 * @param d
104 	 * 
105 	 * @return a Quat
106 	 * 
107 	 */
108 	public Quat set( float d ) {
109 		return set( d, d, d );
110 	}
111 
112 	/*** 
113 	 * 
114 	 * set
115 	 * 
116 	 * @param x
117 	 * @param y
118 	 * @param z
119 	 * 
120 	 * @return a Quat
121 	 * 
122 	 */
123 	public Quat set( float x, float y, float z ) {
124 		return set( x, y, z, 0 );
125 	}
126 
127 	/*** 
128 	 * 
129 	 * set
130 	 * 
131 	 * @param x
132 	 * @param y
133 	 * @param z
134 	 * @param w
135 	 * 
136 	 * @return a Quat
137 	 * 
138 	 */
139 	public Quat set( float x, float y, float z, float w ) {
140 		this.x = x;
141 		this.y = y;
142 		this.z = z;
143 		this.w = w;
144 		return this;
145 	}
146 
147 	/*** 
148 	 * 
149 	 * set
150 	 * 
151 	 * @param point
152 	 * 
153 	 * @return a Quat
154 	 * 
155 	 */
156 	public Quat set( Pt3 point ) {
157 		return set( point.getX(), point.getY(), point.getZ() );
158 	}
159 	
160 	/*** 
161 	 * 
162 	 * set
163 	 * 
164 	 * @param that
165 	 * 
166 	 * @return a Quat
167 	 * 
168 	 */
169 	public Quat set( Quat that ) {
170 		return set( that.x, that.y, that.z, that.w );
171 	}
172 
173 	/*** 
174 	 * 
175 	 * identity
176 	 * 
177 	 * @return a Quat
178 	 * 
179 	 */
180 	public Quat identity() {
181 		return set( 0, 0, 0, 1 );
182 	}
183 
184 	/*** 
185 	 * 
186 	 * rotate
187 	 * 
188 	 * @param angle
189 	 * @param workspace
190 	 * 
191 	 * @return a Quat
192 	 * 
193 	 */
194 	public Quat rotate( Pt3 angle, Quat ws1, Quat ws2, Quat ws3 ) {
195 /*
196 		ws1.set( cos( angle.getX() ), sin( angle.getX() ), 0.0f, 0.0f );
197 		ws2.multiply( this, ws1 ); // ws2 holds result
198 
199 		ws1.set( cos( angle.getY() ), 0.0f, sin( angle.getY() ), 0.0f );
200 		ws3.multiply( ws2, ws1 ); // ws3 holds result
201 		
202 		ws1.set( cos( angle.getZ() ), 0.0f, 0.0f, sin( angle.getZ() ) );
203 		this.multiply( ws3, ws1 ); // this holds result
204 */		
205 		if ( false ) {
206 			ws1.set( cos( angle.getX() ), sin( angle.getX() ), 0.0f, 0.0f );
207 			ws2.multiply( this, ws1 );
208 			this.set( ws2 );
209 		}
210 		
211 		return this;
212 	}
213 
214 	/*** 
215 	 * 
216 	 * invert
217 	 * 
218 	 * @return a Quat
219 	 * 
220 	 */
221 	public Quat invert() {
222 		this.x = -this.x;
223 		this.y = -this.y;
224 		this.z = -this.z;
225 		return this;
226 	}
227 	
228 	/*** 
229 	 * 
230 	 * cos
231 	 * 
232 	 * @param f
233 	 * 
234 	 * @return a float
235 	 * 
236 	 */
237 	public static final float cos( float f ) {
238 		return ( float ) Math.cos( f );
239 	}
240 
241 	/*** 
242 	 * 
243 	 * sin
244 	 * 
245 	 * @param f
246 	 * 
247 	 * @return a float
248 	 * 
249 	 */
250 	public static final float sin( float f ) {
251 		return ( float ) Math.sin( f );
252 	}
253 
254 	/*** 
255 	 * 
256 	 * translate
257 	 * 
258 	 * FIXME: provide an implementation!
259 	 * 
260 	 * @param displacement
261 	 * 
262 	 * @return this
263 	 * 
264 	 */
265 	public Quat translate( Pt3 displacement ) {
266 		this.x += displacement.getX();
267 		this.y += displacement.getY();
268 		this.z += displacement.getZ();
269 		return this;
270 	}
271 
272 	/*** 
273 	 * 
274 	 * scale
275 	 * 
276 	 * @param ratio
277 	 * 
278 	 * @return a Quat
279 	 * 
280 	 */
281 	public Quat scale( Pt3 ratio ) {
282 		this.x *= ratio.getX();
283 		this.y *= ratio.getY();
284 		this.z *= ratio.getZ();
285 		return this;
286 	}
287 
288 	/*** 
289 	 * 
290 	 * add
291 	 * 
292 	 * @param that
293 	 * 
294 	 * @return a Quat
295 	 * 
296 	 */
297 	public Quat add( Quat that ) {
298 		this.x += this.x + that.x;
299 		this.y += this.y + that.y;
300 		this.z += this.z + that.z;
301 		this.w += this.w + that.w;
302 		return this;
303 	}
304 
305 	/*** 
306 	 * 
307 	 * multiply
308 	 * 
309 	 * @param m
310 	 * @param n
311 	 * 
312 	 * @return a Quat
313 	 * 
314 	 */
315 	public Quat multiply( Quat m, Quat n ) {
316 		this.x = ( m.w * n.x ) + ( m.x * n.w ) + ( m.y * n.z ) - ( m.z * n.y );
317 		this.y = ( m.w * n.y ) + ( m.y * n.w ) + ( m.z * n.x ) - ( m.x * n.z );
318 		this.z = ( m.w * n.z ) + ( m.z * n.w ) + ( m.x * n.y ) - ( m.y * n.x );
319 		this.w = ( m.w * n.w ) - ( m.x * n.x ) - ( m.y * n.y ) - ( m.z * n.z );
320 
321 		
322 		//return normalize();
323 		return this;
324 	}
325 
326 	/*** 
327 	 * 
328 	 * normalize
329 	 * 
330 	 * @return a Quat
331 	 * 
332 	 */
333 	public Quat normalize() {
334 		return divide( safetyLen() );
335 	}
336 
337 	/*** 
338 	 * 
339 	 * multiply
340 	 * 
341 	 * @param point
342 	 * @param destination
343 	 * 
344 	 * @return a Pt3
345 	 * 
346 	 */
347 	public Pt3 multiply( Pt3 point, Pt3 destination, Quat ws1, Quat ws2, Quat ws3 ) {
348 /*
349 
350 		$q1 = q.copy();
351 		$q1.invert();
352 		
353 		$q2 = new Quaternion();
354 		$q2.fromPoint($x, $y, $z);
355 		
356 		$q3 = q.copy();
357 		
358 		$q2.concat($q1);	// q2=point * q1=this.invert
359 		$q3.concat($q2);	// q3=this  * q2
360 		// q3 = this * ( point * this.invert() );
361 		
362 		$xp = $q3.x;
363 		$yp = $q3.y;
364 		$zp = $q3.z;
365 */
366 		//$q2.concat($q1);	// point * this.invert
367 		ws1.set( this ).invert();
368 		ws2.set( point );
369 		ws3.multiply( ws2, ws1 );
370 			
371 		//$q3.concat($q2);	// this * ( ws1 )
372 		ws2.multiply( this, ws3 );
373 		
374 		destination.set( 
375 			  ws2.getX()
376 			, ws2.getY()
377 			, ws2.getZ()
378 		);
379 
380 		return destination;
381 	}
382 
383 	/*** 
384 	 * 
385 	 * toString
386 	 * 
387 	 * @return a String
388 	 * 
389 	 */
390 	public String toString() {
391 		return (
392 			super.toString() + "[" +
393 			"x=" + x + "," +
394 			"y=" + y + "," +
395 			"z=" + z + "," +
396 			"w=" + w + "]" 
397 		);
398 	}
399 
400 	/*** 
401 	 * 
402 	 * divide
403 	 * 
404 	 * @param d
405 	 * 
406 	 * @return a Quat
407 	 * 
408 	 */
409 	public Quat divide( float d ) {
410 		x /= d;
411 		y /= d;
412 		z /= d;
413 		w /= d;
414 		return this;
415 	}
416 
417 	/*** 
418 	 * 
419 	 * len2
420 	 * 
421 	 * @return a float
422 	 * 
423 	 */
424 	public float len2() {
425 		return (
426 			+ ( x * x ) 
427 			+ ( y * y ) 
428 			+ ( z * z ) 
429 			+ ( w * w ) 
430 		);
431 	}
432 
433 	/*** 
434 	 * 
435 	 * safetyLen ( returns length unless 0 (then 1)
436 	 * 
437 	 * @return a float
438 	 * 
439 	 */
440 	public float safetyLen() {
441 		float len = len2();
442 		if ( 0 == len ) {
443 			len = 1;
444 		} else {
445 			len = ( float ) Math.sqrt( len );
446 		}
447 		return len;
448 	}
449 
450 	/***
451 	 *
452 	 * Get the value of x
453 	 *
454 	 * @return the value of x
455 	 *
456 	 */
457 	public final float getX() {
458 		return x;
459 	}
460 
461 	/***
462 	 *
463 	 * Set the value of x
464 	 *
465 	 * @param newValue of x
466 	 *
467 	 */
468 	public final void setX( float newValue ) {
469 		x = newValue;
470 	}
471 
472 	/***
473 	 *
474 	 * Get the value of y
475 	 *
476 	 * @return the value of y
477 	 *
478 	 */
479 	public final float getY() {
480 		return y;
481 	}
482 
483 	/***
484 	 *
485 	 * Set the value of y
486 	 *
487 	 * @param newValue of y
488 	 *
489 	 */
490 	public final void setY( float newValue ) {
491 		y = newValue;
492 	}
493 
494 	/***
495 	 *
496 	 * Get the value of z
497 	 *
498 	 * @return the value of z
499 	 *
500 	 */
501 	public final float getZ() {
502 		return z;
503 	}
504 
505 	/***
506 	 *
507 	 * Set the value of z
508 	 *
509 	 * @param newValue of z
510 	 *
511 	 */
512 	public final void setZ( float newValue ) {
513 		z = newValue;
514 	}
515 
516 	/***
517 	 *
518 	 * Get the value of w
519 	 *
520 	 * @return the value of w
521 	 *
522 	 */
523 	public final float getW() {
524 		return w;
525 	}
526 
527 	/***
528 	 *
529 	 * Set the value of w
530 	 *
531 	 * @param newValue of w
532 	 *
533 	 */
534 	public final void setW( float newValue ) {
535 		w = newValue;
536 	}
537 
538 	////
539 
540 	private float x, y, z, w;
541 	
542 };
543 
544 /***
545  *
546  * $Log: Quat.java,v $
547  * Revision 1.4  2005/03/19 17:50:02  brian
548  * repackaging
549  *
550  * Revision 1.3  2005/03/15 05:45:55  brian
551  * closer...
552  *
553  * Revision 1.2  2005/03/14 00:29:38  brian
554  * not quite right..
555  *
556  * Revision 1.1  2005/03/12 04:51:28  brian
557  * right or wrong, here they are...
558  *
559  *
560  */