Merge pull request #1532 from GarageGames/pr/1143
[Torque-3d.git] / Engine / source / math / mathTypes.cpp
blob29c500b609905290f5a0762f54fde383d174292a
1 //-----------------------------------------------------------------------------
2 // Copyright (c) 2012 GarageGames, LLC
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to
6 // deal in the Software without restriction, including without limitation the
7 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 // sell copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 // IN THE SOFTWARE.
21 //-----------------------------------------------------------------------------
23 #include "core/strings/stringFunctions.h"
24 #include "console/consoleTypes.h"
25 #include "console/console.h"
26 #include "console/engineAPI.h"
27 #include "math/mPoint2.h"
28 #include "math/mPoint3.h"
29 #include "math/mMatrix.h"
30 #include "math/mQuat.h"
31 #include "math/mRect.h"
32 #include "math/mBox.h"
33 #include "math/mAngAxis.h"
34 #include "math/mTransform.h"
35 #include "math/mathTypes.h"
36 #include "math/mRandom.h"
37 #include "math/mEase.h"
38 #include "math/mathUtils.h"
40 #include "core/strings/stringUnit.h"
42 IMPLEMENT_SCOPE( MathTypes, Math,, "" );
44 IMPLEMENT_STRUCT( Point2I,
45 Point2I, MathTypes,
46 "" )
48 FIELD( x, x, 1, "X coordinate." )
49 FIELD( y, y, 1, "Y coordinate." )
51 END_IMPLEMENT_STRUCT;
52 IMPLEMENT_STRUCT( Point2F,
53 Point2F, MathTypes,
54 "" )
56 FIELD( x, x, 1, "X coordinate." )
57 FIELD( y, y, 1, "Y coordinate." )
59 END_IMPLEMENT_STRUCT;
60 IMPLEMENT_STRUCT( Point3I,
61 Point3I, MathTypes,
62 "" )
64 FIELD( x, x, 1, "X coordinate." )
65 FIELD( y, y, 1, "Y coordinate." )
66 FIELD( z, z, 1, "Z coordinate." )
68 END_IMPLEMENT_STRUCT;
69 IMPLEMENT_STRUCT( Point3F,
70 Point3F, MathTypes,
71 "" )
73 FIELD( x, x, 1, "X coordinate." )
74 FIELD( y, y, 1, "Y coordinate." )
75 FIELD( z, z, 1, "Z coordinate." )
77 END_IMPLEMENT_STRUCT;
78 IMPLEMENT_STRUCT( Point4F,
79 Point4F, MathTypes,
80 "" )
82 FIELD( x, x, 1, "X coordinate." )
83 FIELD( y, y, 1, "Y coordinate." )
84 FIELD( z, z, 1, "Z coordinate." )
85 FIELD( w, w, 1, "W coordinate." )
87 END_IMPLEMENT_STRUCT;
88 IMPLEMENT_STRUCT( RectI,
89 RectI, MathTypes,
90 "" )
91 END_IMPLEMENT_STRUCT;
92 IMPLEMENT_STRUCT( RectF,
93 RectF, MathTypes,
94 "" )
95 END_IMPLEMENT_STRUCT;
96 IMPLEMENT_STRUCT( MatrixF,
97 MatrixF, MathTypes,
98 "" )
99 END_IMPLEMENT_STRUCT;
100 IMPLEMENT_STRUCT( AngAxisF,
101 AngAxisF, MathTypes,
102 "" )
103 END_IMPLEMENT_STRUCT;
104 IMPLEMENT_STRUCT( TransformF,
105 TransformF, MathTypes,
106 "" )
107 END_IMPLEMENT_STRUCT;
108 IMPLEMENT_STRUCT( Box3F,
109 Box3F, MathTypes,
110 "" )
111 END_IMPLEMENT_STRUCT;
112 IMPLEMENT_STRUCT( EaseF,
113 EaseF, MathTypes,
114 "" )
115 END_IMPLEMENT_STRUCT;
118 //-----------------------------------------------------------------------------
119 // TypePoint2I
120 //-----------------------------------------------------------------------------
121 ConsoleType(Point2I, TypePoint2I, Point2I, "")
122 ImplementConsoleTypeCasters( TypePoint2I, Point2I )
124 ConsoleGetType( TypePoint2I )
126 Point2I *pt = (Point2I *) dptr;
127 static const U32 bufSize = 256;
128 char* returnBuffer = Con::getReturnBuffer(bufSize);
129 dSprintf(returnBuffer, bufSize, "%d %d", pt->x, pt->y);
130 return returnBuffer;
133 ConsoleSetType( TypePoint2I )
135 if(argc == 1)
136 dSscanf(argv[0], "%d %d", &((Point2I *) dptr)->x, &((Point2I *) dptr)->y);
137 else if(argc == 2)
138 *((Point2I *) dptr) = Point2I(dAtoi(argv[0]), dAtoi(argv[1]));
139 else
140 Con::printf("Point2I must be set as { x, y } or \"x y\"");
143 //-----------------------------------------------------------------------------
144 // TypePoint2F
145 //-----------------------------------------------------------------------------
146 ConsoleType(Point2F, TypePoint2F, Point2F, "")
147 ImplementConsoleTypeCasters( TypePoint2F, Point2F )
149 ConsoleGetType( TypePoint2F )
151 Point2F *pt = (Point2F *) dptr;
152 static const U32 bufSize = 256;
153 char* returnBuffer = Con::getReturnBuffer(bufSize);
154 dSprintf(returnBuffer, bufSize, "%g %g", pt->x, pt->y);
155 return returnBuffer;
158 ConsoleSetType( TypePoint2F )
160 if(argc == 1)
161 dSscanf(argv[0], "%g %g", &((Point2F *) dptr)->x, &((Point2F *) dptr)->y);
162 else if(argc == 2)
163 *((Point2F *) dptr) = Point2F(dAtof(argv[0]), dAtof(argv[1]));
164 else
165 Con::printf("Point2F must be set as { x, y } or \"x y\"");
168 //-----------------------------------------------------------------------------
169 // TypePoint3I
170 //-----------------------------------------------------------------------------
171 ConsoleType(Point3I, TypePoint3I, Point3I, "")
172 ImplementConsoleTypeCasters(TypePoint3I, Point3I)
174 ConsoleGetType( TypePoint3I )
176 Point3I *pt = (Point3I *) dptr;
177 static const U32 bufSize = 256;
178 char* returnBuffer = Con::getReturnBuffer(bufSize);
179 dSprintf(returnBuffer, bufSize, "%d %d %d", pt->x, pt->y, pt->z);
180 return returnBuffer;
183 ConsoleSetType( TypePoint3I )
185 if(argc == 1)
186 dSscanf(argv[0], "%d %d %d", &((Point3I *) dptr)->x, &((Point3I *) dptr)->y, &((Point3I *) dptr)->z);
187 else if(argc == 3)
188 *((Point3I *) dptr) = Point3I(dAtoi(argv[0]), dAtoi(argv[1]), dAtoi(argv[2]));
189 else
190 Con::printf("Point3I must be set as { x, y, z } or \"x y z\"");
193 //-----------------------------------------------------------------------------
194 // TypePoint3F
195 //-----------------------------------------------------------------------------
196 ConsoleType(Point3F, TypePoint3F, Point3F, "")
197 ImplementConsoleTypeCasters(TypePoint3F, Point3F)
199 ConsoleGetType( TypePoint3F )
201 Point3F *pt = (Point3F *) dptr;
202 static const U32 bufSize = 256;
203 char* returnBuffer = Con::getReturnBuffer(bufSize);
204 dSprintf(returnBuffer, bufSize, "%g %g %g", pt->x, pt->y, pt->z);
205 return returnBuffer;
208 ConsoleSetType( TypePoint3F )
210 if(argc == 1)
211 dSscanf(argv[0], "%g %g %g", &((Point3F *) dptr)->x, &((Point3F *) dptr)->y, &((Point3F *) dptr)->z);
212 else if(argc == 3)
213 *((Point3F *) dptr) = Point3F(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2]));
214 else
215 Con::printf("Point3F must be set as { x, y, z } or \"x y z\"");
218 //-----------------------------------------------------------------------------
219 // TypePoint4F
220 //-----------------------------------------------------------------------------
221 ConsoleType(Point4F, TypePoint4F, Point4F, "")
222 ImplementConsoleTypeCasters( TypePoint4F, Point4F )
224 ConsoleGetType( TypePoint4F )
226 Point4F *pt = (Point4F *) dptr;
227 static const U32 bufSize = 256;
228 char* returnBuffer = Con::getReturnBuffer(bufSize);
229 dSprintf(returnBuffer, bufSize, "%g %g %g %g", pt->x, pt->y, pt->z, pt->w);
230 return returnBuffer;
233 ConsoleSetType( TypePoint4F )
235 if(argc == 1)
236 dSscanf(argv[0], "%g %g %g %g", &((Point4F *) dptr)->x, &((Point4F *) dptr)->y, &((Point4F *) dptr)->z, &((Point4F *) dptr)->w);
237 else if(argc == 4)
238 *((Point4F *) dptr) = Point4F(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2]), dAtof(argv[3]));
239 else
240 Con::printf("Point4F must be set as { x, y, z, w } or \"x y z w\"");
243 //-----------------------------------------------------------------------------
244 // TypeRectI
245 //-----------------------------------------------------------------------------
246 ConsoleType(RectI, TypeRectI, RectI, "")
247 ImplementConsoleTypeCasters( TypeRectI, RectI )
249 ConsoleGetType( TypeRectI )
251 RectI *rect = (RectI *) dptr;
252 static const U32 bufSize = 256;
253 char* returnBuffer = Con::getReturnBuffer(bufSize);
254 dSprintf(returnBuffer, bufSize, "%d %d %d %d", rect->point.x, rect->point.y,
255 rect->extent.x, rect->extent.y);
256 return returnBuffer;
259 ConsoleSetType( TypeRectI )
261 if(argc == 1)
262 dSscanf(argv[0], "%d %d %d %d", &((RectI *) dptr)->point.x, &((RectI *) dptr)->point.y,
263 &((RectI *) dptr)->extent.x, &((RectI *) dptr)->extent.y);
264 else if(argc == 4)
265 *((RectI *) dptr) = RectI(dAtoi(argv[0]), dAtoi(argv[1]), dAtoi(argv[2]), dAtoi(argv[3]));
266 else
267 Con::printf("RectI must be set as { x, y, w, h } or \"x y w h\"");
270 //-----------------------------------------------------------------------------
271 // TypeRectF
272 //-----------------------------------------------------------------------------
273 ConsoleType(RectF, TypeRectF, RectF, "")
274 ImplementConsoleTypeCasters( TypeRectF, RectF )
276 ConsoleGetType( TypeRectF )
278 RectF *rect = (RectF *) dptr;
279 static const U32 bufSize = 256;
280 char* returnBuffer = Con::getReturnBuffer(bufSize);
281 dSprintf(returnBuffer, bufSize, "%g %g %g %g", rect->point.x, rect->point.y,
282 rect->extent.x, rect->extent.y);
283 return returnBuffer;
286 ConsoleSetType( TypeRectF )
288 if(argc == 1)
289 dSscanf(argv[0], "%g %g %g %g", &((RectF *) dptr)->point.x, &((RectF *) dptr)->point.y,
290 &((RectF *) dptr)->extent.x, &((RectF *) dptr)->extent.y);
291 else if(argc == 4)
292 *((RectF *) dptr) = RectF(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2]), dAtof(argv[3]));
293 else
294 Con::printf("RectF must be set as { x, y, w, h } or \"x y w h\"");
297 //-----------------------------------------------------------------------------
298 // TypeMatrix
299 //-----------------------------------------------------------------------------
300 ConsoleType(MatrixF, TypeMatrixF, MatrixF, "")
301 ImplementConsoleTypeCasters( TypeMatrixF, MatrixF )
303 // Oh merry confusion. Torque stores matrices in row-major order yet to TorqueScript
304 // matrices were passed in column-major order, so we need to stick to this here.
306 ConsoleGetType( TypeMatrixF )
308 MatrixF* mat = ( MatrixF* ) dptr;
310 Point3F col0, col1, col2;
311 mat->getColumn(0, &col0);
312 mat->getColumn(1, &col1);
313 mat->getColumn(2, &col2);
314 static const U32 bufSize = 256;
315 char* returnBuffer = Con::getReturnBuffer(bufSize);
316 dSprintf(returnBuffer,bufSize,"%g %g %g %g %g %g %g %g %g",
317 col0.x, col0.y, col0.z, col1.x, col1.y, col1.z, col2.x, col2.y, col2.z);
318 return returnBuffer;
321 ConsoleSetType( TypeMatrixF )
323 if( argc != 1 )
325 Con::errorf( "MatrixF must be set as \"c0x c0y c0z c1x c1y c1z c2x c2y c2z\"" );
326 return;
329 Point3F col0, col1, col2;
330 dSscanf( argv[ 0 ], "%g %g %g %g %g %g %g %g %g",
331 &col0.x, &col0.y, &col0.z, &col1.x, &col1.y, &col1.z, &col2.x, &col2.y, &col2.z );
333 MatrixF* mat = ( MatrixF* ) dptr;
335 mat->setColumn( 0, col0 );
336 mat->setColumn( 1, col1 );
337 mat->setColumn( 2, col2 );
340 //-----------------------------------------------------------------------------
341 // TypeMatrixPosition
342 //-----------------------------------------------------------------------------
343 ConsoleType(MatrixPosition, TypeMatrixPosition, MatrixF, "")
345 ConsoleGetType( TypeMatrixPosition )
347 F32 *col = (F32 *) dptr + 3;
348 static const U32 bufSize = 256;
349 char* returnBuffer = Con::getReturnBuffer(bufSize);
350 if(col[12] == 1.f)
351 dSprintf(returnBuffer, bufSize, "%g %g %g", col[0], col[4], col[8]);
352 else
353 dSprintf(returnBuffer, bufSize, "%g %g %g %g", col[0], col[4], col[8], col[12]);
354 return returnBuffer;
357 ConsoleSetType( TypeMatrixPosition )
359 F32 *col = ((F32 *) dptr) + 3;
360 if (argc == 1)
362 col[0] = col[4] = col[8] = 0.f;
363 col[12] = 1.f;
364 dSscanf(argv[0], "%g %g %g %g", &col[0], &col[4], &col[8], &col[12]);
366 else if (argc <= 4)
368 for (S32 i = 0; i < argc; i++)
369 col[i << 2] = dAtof(argv[i]);
371 else
372 Con::printf("Matrix position must be set as { x, y, z, w } or \"x y z w\"");
375 //-----------------------------------------------------------------------------
376 // TypeMatrixRotation
377 //-----------------------------------------------------------------------------
378 ConsoleType(MatrixRotation, TypeMatrixRotation, MatrixF, "")
380 ConsoleGetType( TypeMatrixRotation )
382 AngAxisF aa(*(MatrixF *) dptr);
383 aa.axis.normalize();
384 static const U32 bufSize = 256;
385 char* returnBuffer = Con::getReturnBuffer(bufSize);
386 dSprintf(returnBuffer,bufSize,"%g %g %g %g",aa.axis.x,aa.axis.y,aa.axis.z,mRadToDeg(aa.angle));
387 return returnBuffer;
390 ConsoleSetType( TypeMatrixRotation )
392 // DMM: Note that this will ONLY SET the ULeft 3x3 submatrix.
394 AngAxisF aa(Point3F(0,0,0),0);
395 if (argc == 1)
397 dSscanf(argv[0], "%g %g %g %g", &aa.axis.x, &aa.axis.y, &aa.axis.z, &aa.angle);
398 aa.angle = mDegToRad(aa.angle);
400 else if (argc == 4)
402 for (S32 i = 0; i < argc; i++)
403 ((F32*)&aa)[i] = dAtof(argv[i]);
404 aa.angle = mDegToRad(aa.angle);
406 else
407 Con::printf("Matrix rotation must be set as { x, y, z, angle } or \"x y z angle\"");
410 MatrixF temp;
411 aa.setMatrix(&temp);
413 F32* pDst = *(MatrixF *)dptr;
414 const F32* pSrc = temp;
415 for (U32 i = 0; i < 3; i++)
416 for (U32 j = 0; j < 3; j++)
417 pDst[i*4 + j] = pSrc[i*4 + j];
420 //-----------------------------------------------------------------------------
421 // TypeAngAxisF
422 //-----------------------------------------------------------------------------
423 ConsoleType(AngAxisF, TypeAngAxisF, AngAxisF, "")
424 ImplementConsoleTypeCasters( TypeAngAxisF, AngAxisF )
426 ConsoleGetType( TypeAngAxisF )
428 AngAxisF* aa = ( AngAxisF* ) dptr;
429 static const U32 bufSize = 256;
430 char* returnBuffer = Con::getReturnBuffer(bufSize);
431 dSprintf(returnBuffer,bufSize,"%g %g %g %g",aa->axis.x,aa->axis.y,aa->axis.z,mRadToDeg(aa->angle));
432 return returnBuffer;
435 ConsoleSetType( TypeAngAxisF )
437 // DMM: Note that this will ONLY SET the ULeft 3x3 submatrix.
439 AngAxisF* aa = ( AngAxisF* ) dptr;
440 if (argc == 1)
442 dSscanf(argv[0], "%g %g %g %g", &aa->axis.x, &aa->axis.y, &aa->axis.z, &aa->angle);
443 aa->angle = mDegToRad(aa->angle);
445 else if (argc == 4)
447 for (S32 i = 0; i < argc; i++)
448 ((F32*)&aa)[i] = dAtof(argv[i]);
449 aa->angle = mDegToRad(aa->angle);
451 else
452 Con::printf("AngAxisF must be set as { x, y, z, angle } or \"x y z angle\"");
456 //-----------------------------------------------------------------------------
457 // TypeTransformF
458 //-----------------------------------------------------------------------------
460 const TransformF TransformF::Identity( Point3F::Zero, AngAxisF( Point3F( 0, 0, 1 ), 0) );
462 ConsoleType(TransformF, TypeTransformF, TransformF, "")
463 ImplementConsoleTypeCasters( TypeTransformF, TransformF )
465 ConsoleGetType( TypeTransformF )
467 TransformF* aa = ( TransformF* ) dptr;
468 static const U32 bufSize = 256;
469 char* returnBuffer = Con::getReturnBuffer(bufSize);
470 dSprintf( returnBuffer, bufSize, "%g %g %g %g %g %g %g",
471 aa->mPosition.x, aa->mPosition.y, aa->mPosition.z,
472 aa->mOrientation.axis.x, aa->mOrientation.axis.y, aa->mOrientation.axis.z, aa->mOrientation.angle );
473 return returnBuffer;
476 ConsoleSetType( TypeTransformF )
478 TransformF* aa = ( TransformF* ) dptr;
479 if( argc == 1 )
481 U32 count = dSscanf( argv[ 0 ], "%g %g %g %g %g %g %g",
482 &aa->mPosition.x, &aa->mPosition.y, &aa->mPosition.z,
483 &aa->mOrientation.axis.x, &aa->mOrientation.axis.y, &aa->mOrientation.axis.z, &aa->mOrientation.angle );
485 aa->mHasRotation = ( count == 7 );
487 else if( argc == 7 )
489 aa->mPosition.x = dAtof( argv[ 0 ] );
490 aa->mPosition.y = dAtof( argv[ 1 ] );
491 aa->mPosition.z = dAtof( argv[ 2 ] );
492 aa->mOrientation.axis.x = dAtof( argv[ 3 ] );
493 aa->mOrientation.axis.y = dAtof( argv[ 4 ] );
494 aa->mOrientation.axis.z = dAtof( argv[ 5 ] );
495 aa->mOrientation.angle = dAtof( argv[ 6 ] );
497 else
498 Con::errorf( "TransformF must be set as { px, py, pz, x, y, z, angle } or \"px py pz x y z angle\"");
503 //-----------------------------------------------------------------------------
504 // TypeBox3F
505 //-----------------------------------------------------------------------------
506 ConsoleType(Box3F, TypeBox3F, Box3F, "")
507 ImplementConsoleTypeCasters( TypeBox3F, Box3F )
509 ConsoleGetType( TypeBox3F )
511 const Box3F* pBox = (const Box3F*)dptr;
513 static const U32 bufSize = 256;
514 char* returnBuffer = Con::getReturnBuffer(bufSize);
515 dSprintf(returnBuffer, bufSize, "%g %g %g %g %g %g",
516 pBox->minExtents.x, pBox->minExtents.y, pBox->minExtents.z,
517 pBox->maxExtents.x, pBox->maxExtents.y, pBox->maxExtents.z);
519 return returnBuffer;
522 ConsoleSetType( TypeBox3F )
524 Box3F* pDst = (Box3F*)dptr;
526 if (argc == 1)
528 U32 args = dSscanf(argv[0], "%g %g %g %g %g %g",
529 &pDst->minExtents.x, &pDst->minExtents.y, &pDst->minExtents.z,
530 &pDst->maxExtents.x, &pDst->maxExtents.y, &pDst->maxExtents.z);
531 AssertWarn(args == 6, "Warning, box probably not read properly");
533 else
535 Con::printf("Box3F must be set as \"xMin yMin zMin xMax yMax zMax\"");
540 //-----------------------------------------------------------------------------
541 // TypeEaseF
542 //-----------------------------------------------------------------------------
543 ConsoleType(EaseF, TypeEaseF, EaseF, "")
544 ImplementConsoleTypeCasters( TypeEaseF, EaseF )
546 ConsoleGetType( TypeEaseF )
548 const EaseF* pEase = (const EaseF*)dptr;
550 static const U32 bufSize = 256;
551 char* returnBuffer = Con::getReturnBuffer(bufSize);
552 dSprintf(returnBuffer, bufSize, "%d %d %g %g",
553 pEase->dir, pEase->type, pEase->param[0], pEase->param[1]);
555 return returnBuffer;
558 ConsoleSetType( TypeEaseF )
560 EaseF* pDst = (EaseF*)dptr;
562 // defaults...
563 pDst->param[0] = -1.0f;
564 pDst->param[1] = -1.0f;
565 if (argc == 1) {
566 U32 args = dSscanf(argv[0], "%d %d %f %f", // the two params are optional and assumed -1 if not present...
567 &pDst->dir, &pDst->type, &pDst->param[0],&pDst->param[1]);
568 if( args < 2 )
569 Con::warnf( "Warning, EaseF probably not read properly" );
570 } else {
571 Con::printf("EaseF must be set as \"dir type [param0 param1]\"");
576 //-----------------------------------------------------------------------------
578 DefineConsoleFunction( VectorAdd, VectorF, ( VectorF a, VectorF b ),,
579 "Add two vectors.\n"
580 "@param a The first vector.\n"
581 "@param b The second vector.\n"
582 "@return The vector @a a + @a b.\n\n"
583 "@tsexample\n"
584 "//-----------------------------------------------------------------------------\n"
585 "//\n"
586 "// VectorAdd( %a, %b );\n"
587 "//\n"
588 "// The sum of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
589 "//\n"
590 "// a + b = ( ax + bx, ay + by, az + bz )\n"
591 "//\n"
592 "//-----------------------------------------------------------------------------\n"
593 "%a = \"1 0 0\";\n"
594 "%b = \"0 1 0\";\n\n"
595 "// %r = \"( 1 + 0, 0 + 1, 0 + 0 )\";\n"
596 "// %r = \"1 1 0\";\n"
597 "%r = VectorAdd( %a, %b );\n"
598 "@endtsexample\n\n"
599 "@ingroup Vectors")
601 return a + b;
604 //-----------------------------------------------------------------------------
606 DefineConsoleFunction( VectorSub, VectorF, ( VectorF a, VectorF b ),,
607 "Subtract two vectors.\n"
608 "@param a The first vector.\n"
609 "@param b The second vector.\n"
610 "@return The vector @a a - @a b.\n\n"
611 "@tsexample\n"
612 "//-----------------------------------------------------------------------------\n"
613 "//\n"
614 "// VectorSub( %a, %b );\n"
615 "//\n"
616 "// The difference of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
617 "//\n"
618 "// a - b = ( ax - bx, ay - by, az - bz )\n"
619 "//\n"
620 "//-----------------------------------------------------------------------------\n\n"
622 "%a = \"1 0 0\";\n"
623 "%b = \"0 1 0\";\n\n"
625 "// %r = \"( 1 - 0, 0 - 1, 0 - 0 )\";\n"
626 "// %r = \"1 -1 0\";\n"
627 "%r = VectorSub( %a, %b );\n"
628 "@endtsexample\n\n"
629 "@ingroup Vectors" )
631 return a - b;
634 //-----------------------------------------------------------------------------
636 DefineConsoleFunction( VectorScale, VectorF, ( VectorF a, F32 scalar ),,
637 "Scales a vector by a scalar.\n"
638 "@param a The vector to scale.\n"
639 "@param scalar The scale factor.\n"
640 "@return The vector @a a * @a scalar.\n\n"
641 "@tsexample\n"
642 "//-----------------------------------------------------------------------------\n"
643 "//\n"
644 "// VectorScale( %a, %v );\n"
645 "//\n"
646 "// Scaling vector a, (ax, ay, az), but the scalar, v, is:\n"
647 "//\n"
648 "// a * v = ( ax * v, ay * v, az * v )\n"
649 "//\n"
650 "//-----------------------------------------------------------------------------\n\n"
652 "%a = \"1 1 0\";\n"
653 "%v = \"2\";\n\n"
655 "// %r = \"( 1 * 2, 1 * 2, 0 * 2 )\";\n"
656 "// %r = \"2 2 0\";\n"
657 "%r = VectorScale( %a, %v );\n"
658 "@endtsexample\n\n"
659 "@ingroup Vectors" )
661 return a * scalar;
663 DefineConsoleFunction( VectorMul, VectorF, ( VectorF a, VectorF b ),,
664 "Multiplies two vectors.\n"
665 "@param a The first vector.\n"
666 "@param b The second vector.\n"
667 "@return The vector @a a * @a b.\n\n"
668 "@tsexample\n"
669 "//-----------------------------------------------------------------------------\n"
670 "//\n"
671 "// VectorMul( %a, %b );\n"
672 "//\n"
673 "// The multiplication of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
674 "//\n"
675 "// a * b = ( ax * bx, ay * by, az * bz )\n"
676 "//\n"
677 "//-----------------------------------------------------------------------------\n\n"
679 "%a = \"1 0 0\";\n"
680 "%b = \"0 1 0\";\n\n"
682 "// %r = \"( 1 * 0, 0 * 1, 0 * 0 )\";\n"
683 "// %r = \"0 0 0\";\n"
684 "%r = VectorMul( %a, %b );\n"
685 "@endtsexample\n\n"
686 "@ingroup Vectors" )
688 return a * b;
691 DefineConsoleFunction( VectorDiv, VectorF, ( VectorF a, VectorF b ),,
692 "Divide two vectors.\n"
693 "@param a The first vector.\n"
694 "@param b The second vector.\n"
695 "@return The vector @a a / @a b.\n\n"
696 "@tsexample\n"
697 "//-----------------------------------------------------------------------------\n"
698 "//\n"
699 "// VectorDiv( %a, %b );\n"
700 "//\n"
701 "// The division of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
702 "//\n"
703 "// a * b = ( ax / bx, ay / by, az / bz )\n"
704 "//\n"
705 "//-----------------------------------------------------------------------------\n\n"
707 "%a = \"1 1 1\";\n"
708 "%b = \"2 2 2\";\n\n"
710 "// %r = \"( 1 / 2, 1 / 2, 1 / 2 )\";\n"
711 "// %r = \"0.5 0.5 0.5\";\n"
712 "%r = VectorDiv( %a, %b );\n"
713 "@endtsexample\n\n"
714 "@ingroup Vectors" )
716 //this is kind of bad, but so is dividing by 0
717 if(b.x == 0) b.x = 0.000001f;
718 if(b.y == 0) b.y = 0.000001f;
719 if(b.z == 0) b.z = 0.000001f;
721 return a / b;
724 //-----------------------------------------------------------------------------
726 DefineConsoleFunction( VectorNormalize, VectorF, ( VectorF v ),,
727 "Brings a vector into its unit form, i.e. such that it has the magnitute 1.\n"
728 "@param v The vector to normalize.\n"
729 "@return The vector @a v scaled to length 1.\n\n"
730 "@tsexample\n"
731 "//-----------------------------------------------------------------------------\n"
732 "//\n"
733 "// VectorNormalize( %a );\n"
734 "//\n"
735 "// The normalized vector a, (ax, ay, az), is:\n"
736 "//\n"
737 "// a^ = a / ||a||\n"
738 "// = ( ax / ||a||, ay / ||a||, az / ||a|| )\n"
739 "//\n"
740 "//-----------------------------------------------------------------------------\n\n"
742 "%a = \"1 1 0\";\n"
743 "%l = 1.414;\n\n"
745 "// %r = \"( 1 / 1.141, 1 / 1.141, 0 / 1.141 )\";\n"
746 "// %r = \"0.707 0.707 0\";\n"
747 "%r = VectorNormalize( %a );\n"
748 "@endtsexample\n\n"
749 "@ingroup Vectors" )
751 VectorF n( v );
752 n.normalizeSafe();
753 return n;
756 //-----------------------------------------------------------------------------
758 DefineConsoleFunction( VectorDot, F32, ( VectorF a, VectorF b ),,
759 "Compute the dot product of two vectors.\n"
760 "@param a The first vector.\n"
761 "@param b The second vector.\n"
762 "@return The dot product @a a * @a b.\n\n"
763 "@tsexample\n"
764 "//-----------------------------------------------------------------------------\n"
765 "//\n"
766 "// VectorDot( %a, %b );\n"
767 "//\n"
768 "// The dot product between vector a, (ax, ay, az), and vector b, (bx, by, bz), is:\n"
769 "//\n"
770 "// a . b = ( ax * bx + ay * by + az * bz )\n"
771 "//\n"
772 "//-----------------------------------------------------------------------------\n\n"
774 "%a = \"1 1 0\";\n"
775 "%b = \"2 0 1\";\n\n"
777 "// %r = \"( 1 * 2 + 1 * 0 + 0 * 1 )\";\n"
778 "// %r = 2;\n"
779 "%r = VectorDot( %a, %b );\n"
780 "@endtsexample\n\n"
781 "@ingroup Vectors" )
783 return mDot( a, b );
786 //-----------------------------------------------------------------------------
788 DefineConsoleFunction( VectorCross, VectorF, ( VectorF a, VectorF b ),,
789 "Calculcate the cross product of two vectors.\n"
790 "@param a The first vector.\n"
791 "@param b The second vector.\n"
792 "@return The cross product @a x @a b.\n\n"
793 "@tsexample\n"
794 "//-----------------------------------------------------------------------------\n"
795 "//\n"
796 "// VectorCross( %a, %b );\n"
797 "//\n"
798 "// The cross product of vector a, (ax, ay, az), and vector b, (bx, by, bz), is\n"
799 "//\n"
800 "// a x b = ( ( ay * bz ) - ( az * by ), ( az * bx ) - ( ax * bz ), ( ax * by ) - ( ay * bx ) )\n"
801 "//\n"
802 "//-----------------------------------------------------------------------------\n\n"
804 "%a = \"1 1 0\";\n"
805 "%b = \"2 0 1\";\n\n"
807 "// %r = \"( ( 1 * 1 ) - ( 0 * 0 ), ( 0 * 2 ) - ( 1 * 1 ), ( 1 * 0 ) - ( 1 * 2 ) )\";\n"
808 "// %r = \"1 -1 -2\";\n"
809 "%r = VectorCross( %a, %b );\n"
810 "@endtsexample\n\n"
811 "@ingroup Vectors" )
813 VectorF v;
814 mCross( a, b, &v );
815 return v;
818 //-----------------------------------------------------------------------------
820 DefineConsoleFunction( VectorDist, F32, ( VectorF a, VectorF b ),,
821 "Compute the distance between two vectors.\n"
822 "@param a The first vector.\n"
823 "@param b The second vector.\n"
824 "@return The length( @a b - @a a ).\n\n"
825 "@tsexample\n"
826 "//-----------------------------------------------------------------------------\n"
827 "//\n"
828 "// VectorDist( %a, %b );\n"
829 "//\n"
830 "// The distance between vector a, (ax, ay, az), and vector b, (bx, by, bz), is\n"
831 "//\n"
832 "// a -> b = ||( b - a )||\n"
833 "// = ||( bx - ax, by - ay, bz - az )||\n"
834 "// = mSqrt( ( bx - ax ) * ( bx - ax ) + ( by - ay ) * ( by - ay ) + ( bz - az ) * ( bz - az ) )\n"
835 "//\n"
836 "//-----------------------------------------------------------------------------\n\n"
838 "%a = \"1 1 0\";\n"
839 "%b = \"2 0 1\";\n\n"
841 "// %r = mSqrt( ( 2 - 1 ) * ( 2 - 1) + ( 0 - 1 ) * ( 0 - 1 ) + ( 1 - 0 ) * ( 1 - 0 ) );\n"
842 "// %r = mSqrt( 3 );\n"
843 "%r = VectorDist( %a, %b );\n"
844 "@endtsexample\n\n"
845 "@ingroup Vectors" )
847 VectorF v = b - a;
848 return v.len();
851 //-----------------------------------------------------------------------------
853 DefineConsoleFunction( VectorMidPoint, VectorF, ( VectorF a, VectorF b ),,
854 "Gets the midpoint between the two vectors.\n"
855 "@param a The first vector.\n"
856 "@param b The second vector.\n"
857 "@return The vector (@a a + @a b) / 2.\n\n"
858 "@tsexample\n"
859 "//-----------------------------------------------------------------------------\n"
860 "//\n"
861 "// VectorMidPoint( %a, %b );\n"
862 "//\n"
863 "// The midpoint of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
864 "//\n"
865 "// (a + b)/2 = ( (ax + bx) /2, ay + by) /2, (az + bz) /2 )\n"
866 "//\n"
867 "//-----------------------------------------------------------------------------\n"
868 // "%a = \"1 0 0\";\n"
869 // "%b = \"0 1 0\";\n\n"
870 // "// %r = \"( 1 + 0, 0 + 1, 0 + 0 )\";\n"
871 // "// %r = \"1 1 0\";\n"
872 // "%r = VectorAdd( %a, %b );\n"
873 "@endtsexample\n\n"
874 "@ingroup Vectors")
876 return (a + b)/2.0f;
879 //-----------------------------------------------------------------------------
881 DefineConsoleFunction( VectorLen, F32, ( VectorF v ),,
882 "Calculate the magnitude of the given vector.\n"
883 "@param v A vector.\n"
884 "@return The length of vector @a v.\n\n"
885 "@tsexample\n"
886 "//-----------------------------------------------------------------------------\n"
887 "//\n"
888 "// VectorLen( %a );\n"
889 "//\n"
890 "// The length or magnitude of vector a, (ax, ay, az), is:\n"
891 "//\n"
892 "// ||a|| = Sqrt( ax * ax + ay * ay + az * az )\n"
893 "//\n"
894 "//-----------------------------------------------------------------------------\n\n"
896 "%a = \"1 1 0\";\n\n"
898 "// %r = mSqrt( 1 * 1 + 1 * 1 + 0 * 0 );\n"
899 "// %r = mSqrt( 2 );\n"
900 "// %r = 1.414;\n"
901 "%r = VectorLen( %a );\n"
902 "@endtsexample\n\n"
903 "@ingroup Vectors" )
905 return v.len();
908 //-----------------------------------------------------------------------------
910 DefineConsoleFunction( VectorOrthoBasis, MatrixF, ( AngAxisF aa ),,
911 "Create an orthogonal basis from the given vector.\n"
912 "@param aaf The vector to create the orthogonal basis from.\n"
913 "@return A matrix representing the orthogonal basis.\n"
914 "@ingroup Vectors" )
916 MatrixF mat;
917 aa.setMatrix(&mat);
918 return mat;
921 //-----------------------------------------------------------------------------
923 //ConsoleFunction(VectorRot, const char*, 3, 3, "(Vector3F, float) rotate a vector in 2d")
924 DefineConsoleFunction( VectorRot, const char*, (Point3F v, F32 angle), , "(Vector3F, float) rotate a vector in 2d")
926 //VectorF v(0,0,0);
927 //dSscanf(argv[1],"%g %g %g",&v.x,&v.y,&v.z);
928 //dSscanf(axeStr,"%g %g %g",&v.x,&v.y,&v.z);
930 //float angle = dAtof(argv[2]);
931 //float angle = dAtof(angleStr);
933 float x = 0, y = 0;
935 x = v.x * cos(angle) - v.y * sin(angle);
936 y = v.x * sin(angle) + v.y * cos(angle);
938 char* returnBuffer = Con::getReturnBuffer(256);
939 dSprintf(returnBuffer,256,"%g %g %g", x, y, v.z);
940 return returnBuffer;
943 DefineConsoleFunction( VectorLerp, VectorF, ( VectorF a, VectorF b, F32 t ),,
944 "Linearly interpolate between two vectors by @a t.\n"
945 "@param a Vector to start interpolation from.\n"
946 "@param b Vector to interpolate to.\n"
947 "@param t Interpolation factor (0-1). At zero, @a a is returned and at one, @a b is returned. In between, an interpolated vector "
948 "between @a a and @a b is returned.\n"
949 "@return An interpolated vector between @a a and @a b.\n\n"
950 "@tsexample\n"
951 "//-----------------------------------------------------------------------------\n"
952 "//\n"
953 "// VectorLerp( %a, %b );\n"
954 "//\n"
955 "// The point between vector a, (ax, ay, az), and vector b, (bx, by, bz), which is\n"
956 "// weighted by the interpolation factor, t, is\n"
957 "//\n"
958 "// r = a + t * ( b - a )\n"
959 "// = ( ax + t * ( bx - ax ), ay + t * ( by - ay ), az + t * ( bz - az ) )\n"
960 "//\n"
961 "//-----------------------------------------------------------------------------\n\n"
963 "%a = \"1 1 0\";\n"
964 "%b = \"2 0 1\";\n"
965 "%v = \"0.25\";\n\n"
967 "// %r = \"( 1 + 0.25 * ( 2 - 1 ), 1 + 0.25 * ( 0 - 1 ), 0 + 0.25 * ( 1 - 0 ) )\";\n"
968 "// %r = \"1.25 0.75 0.25\";\n"
969 "%r = VectorLerp( %a, %b );\n"
970 "@endtsexample\n\n"
971 "@ingroup Vectors" )
973 VectorF c;
974 c.interpolate( a, b, t );
976 return c;
979 //-----------------------------------------------------------------------------
981 DefineConsoleFunction( MatrixCreate, TransformF, ( VectorF position, AngAxisF orientation ),,
982 "Create a transform from the given translation and orientation.\n"
983 "@param position The translation vector for the transform.\n"
984 "@param orientation The axis and rotation that orients the transform.\n"
985 "@return A transform based on the given position and orientation.\n"
986 "@ingroup Matrices" )
988 TransformF transform( position, orientation );
989 return transform;
992 //-----------------------------------------------------------------------------
994 DefineConsoleFunction( MatrixCreateFromEuler, TransformF, ( Point3F angles ),,
995 "@Create a matrix from the given rotations.\n\n"
996 "@param Vector3F X, Y, and Z rotation in *radians*.\n"
997 "@return A transform based on the given orientation.\n"
998 "@ingroup Matrices" )
1000 QuatF rotQ( angles );
1001 AngAxisF aa;
1002 aa.set(rotQ);
1004 return TransformF( Point3F::Zero, aa );
1007 //-----------------------------------------------------------------------------
1009 DefineConsoleFunction( MatrixMultiply, TransformF, ( TransformF left, TransformF right ),,
1010 "@brief Multiply the two matrices.\n\n"
1011 "@param left First transform.\n"
1012 "@param right Right transform.\n"
1013 "@return Concatenation of the two transforms.\n"
1014 "@ingroup Matrices" )
1016 MatrixF m1 = left.getMatrix();
1017 MatrixF m2 = right.getMatrix();
1019 m1.mul( m2 );
1021 return TransformF( m1 );
1024 //-----------------------------------------------------------------------------
1026 DefineConsoleFunction( MatrixMulVector, VectorF, ( TransformF transform, VectorF vector ),,
1027 "@brief Multiply the vector by the transform assuming that w=0.\n\n"
1028 "This function will multiply the given vector by the given transform such that translation will "
1029 "not affect the vector.\n\n"
1030 "@param transform A transform.\n"
1031 "@param vector A vector.\n"
1032 "@return The transformed vector.\n"
1033 "@ingroup Matrices")
1035 MatrixF m = transform.getMatrix();
1036 m.mulV( vector );
1037 return vector;
1040 //-----------------------------------------------------------------------------
1042 DefineConsoleFunction( MatrixMulPoint, Point3F, ( TransformF transform, Point3F point ),,
1043 "@brief Multiply the given point by the given transform assuming that w=1.\n\n"
1044 "This function will multiply the given vector such that translation with take effect.\n"
1045 "@param transform A transform.\n"
1046 "@param point A vector.\n"
1047 "@return The transformed vector.\n"
1048 "@ingroup Matrices")
1050 MatrixF m = transform.getMatrix();
1051 m.mulP( point );
1052 return point;
1055 ConsoleFunctionGroupEnd(MatrixMath);
1057 //------------------------------------------------------------------------------
1059 DefineConsoleFunction( getBoxCenter, Point3F, ( Box3F box ),,
1060 "Get the center point of an axis-aligned box.\n\n"
1061 "@param b A Box3F, in string format using \"minExtentX minExtentY minExtentZ maxExtentX maxExtentY maxExtentZ\"\n"
1062 "@return Center of the box.\n"
1063 "@ingroup Math")
1065 return box.getCenter();
1068 //------------------------------------------------------------------------------
1070 DefineEngineFunction( setRandomSeed, void, ( S32 seed ), ( -1 ),
1071 "Set the current seed for the random number generator.\n"
1072 "Based on this seed, a repeatable sequence of numbers will be produced by getRandom().\n"
1073 "@param seed The seed with which to initialize the randon number generator with. The same seed will always leed to"
1074 "the same sequence of pseudo-random numbers.\n"
1075 "If -1, the current timestamp will be used as the seed which is a good basis for randomization.\n"
1076 "@ingroup Random" )
1078 if( seed == -1 )
1079 seed = Platform::getRealMilliseconds();
1081 MRandomLCG::setGlobalRandSeed( seed );
1084 //------------------------------------------------------------------------------
1086 DefineEngineFunction( getRandomSeed, S32, (),,
1087 "Get the current seed used by the random number generator.\n"
1088 "@return The current random number generator seed value.\n"
1089 "@ingroup Random" )
1091 return gRandGen.getSeed();
1094 //------------------------------------------------------------------------------
1096 S32 mRandI(S32 i1, S32 i2)
1098 return gRandGen.randI(i1, i2);
1101 F32 mRandF(F32 f1, F32 f2)
1103 return gRandGen.randF(f1, f2);
1106 F32 mRandF()
1108 return gRandGen.randF();
1111 DefineConsoleFunction(getRandom, F32, (S32 a, S32 b), (S32_MAX, S32_MAX),
1112 "( int a, int b ) "
1113 "@brief Returns a random number based on parameters passed in..\n\n"
1114 "If no parameters are passed in, getRandom() will return a float between 0.0 and 1.0. If one "
1115 "parameter is passed an integer between 0 and the passed in value will be returned. Two parameters will "
1116 "return an integer between the specified numbers.\n\n"
1117 "@param a If this is the only parameter, a number between 0 and a is returned. Elsewise represents the lower bound.\n"
1118 "@param b Upper bound on the random number. The random number will be <= @a b.\n"
1119 "@return A pseudo-random integer between @a a and @a b, between 0 and a, or a "
1120 "float between 0.0 and 1.1 depending on usage.\n\n"
1121 "@note All parameters are optional."
1122 "@see setRandomSeed\n"
1123 "@ingroup Random" )
1125 if (a != S32_MAX)
1127 if (b == S32_MAX)
1128 return F32(gRandGen.randI(0, getMax(a, 0)));
1129 else
1131 S32 min = a;
1132 S32 max = b;
1133 if (min > max)
1135 S32 t = min;
1136 min = max;
1137 max = t;
1139 return F32(gRandGen.randI(min, max));
1142 return gRandGen.randF();
1145 //------------------------------------------------------------------------------