LCOV - code coverage report
Current view: top level - Core/Scripting - OOJSVector.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 50 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOJSVector.m
       4             : 
       5             : Oolite
       6             : Copyright (C) 2004-2013 Giles C Williams and contributors
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #import "OOJSVector.h"
      26             : #import "OOJavaScriptEngine.h"
      27             : 
      28             : #if OOLITE_GNUSTEP
      29             : #import <GNUstepBase/GSObjCRuntime.h>
      30             : #else
      31             : #import <objc/objc-runtime.h>
      32             : #endif
      33             : 
      34             : #import "OOConstToString.h"
      35             : #import "OOJSEntity.h"
      36             : #import "OOJSQuaternion.h"
      37             : 
      38             : 
      39           0 : static JSObject *sVectorPrototype;
      40             : 
      41             : 
      42             : static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, HPVector *outVector, NSString *method)  NONNULL_FUNC;
      43             : 
      44             : 
      45             : static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
      46             : static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value);
      47             : static void VectorFinalize(JSContext *context, JSObject *this);
      48             : static JSBool VectorConstruct(JSContext *context, uintN argc, jsval *vp);
      49             : 
      50             : // Methods
      51             : static JSBool VectorToString(JSContext *context, uintN argc, jsval *vp);
      52             : static JSBool VectorToSource(JSContext *context, uintN argc, jsval *vp);
      53             : static JSBool VectorAdd(JSContext *context, uintN argc, jsval *vp);
      54             : static JSBool VectorSubtract(JSContext *context, uintN argc, jsval *vp);
      55             : static JSBool VectorDistanceTo(JSContext *context, uintN argc, jsval *vp);
      56             : static JSBool VectorSquaredDistanceTo(JSContext *context, uintN argc, jsval *vp);
      57             : static JSBool VectorMultiply(JSContext *context, uintN argc, jsval *vp);
      58             : static JSBool VectorDot(JSContext *context, uintN argc, jsval *vp);
      59             : static JSBool VectorAngleTo(JSContext *context, uintN argc, jsval *vp);
      60             : static JSBool VectorFromCoordinateSystem(JSContext *context, uintN argc, jsval *vp);
      61             : static JSBool VectorToCoordinateSystem(JSContext *context, uintN argc, jsval *vp);
      62             : static JSBool VectorCross(JSContext *context, uintN argc, jsval *vp);
      63             : static JSBool VectorTripleProduct(JSContext *context, uintN argc, jsval *vp);
      64             : static JSBool VectorDirection(JSContext *context, uintN argc, jsval *vp);
      65             : static JSBool VectorMagnitude(JSContext *context, uintN argc, jsval *vp);
      66             : static JSBool VectorSquaredMagnitude(JSContext *context, uintN argc, jsval *vp);
      67             : static JSBool VectorRotationTo(JSContext *context, uintN argc, jsval *vp);
      68             : static JSBool VectorRotateBy(JSContext *context, uintN argc, jsval *vp);
      69             : static JSBool VectorToArray(JSContext *context, uintN argc, jsval *vp);
      70             : 
      71             : // Static methods
      72             : static JSBool VectorStaticInterpolate(JSContext *context, uintN argc, jsval *vp);
      73             : static JSBool VectorStaticRandom(JSContext *context, uintN argc, jsval *vp);
      74             : static JSBool VectorStaticRandomDirection(JSContext *context, uintN argc, jsval *vp);
      75             : static JSBool VectorStaticRandomDirectionAndLength(JSContext *context, uintN argc, jsval *vp);
      76             : 
      77             : 
      78           0 : static JSClass sVectorClass =
      79             : {
      80             :         "Vector3D",
      81             :         JSCLASS_HAS_PRIVATE,
      82             :         
      83             :         JS_PropertyStub,                // addProperty
      84             :         JS_PropertyStub,                // delProperty
      85             :         VectorGetProperty,              // getProperty
      86             :         VectorSetProperty,              // setProperty
      87             :         JS_EnumerateStub,               // enumerate
      88             :         JS_ResolveStub,                 // resolve
      89             :         JS_ConvertStub,                 // convert
      90             :         VectorFinalize,                 // finalize
      91             :         JSCLASS_NO_OPTIONAL_MEMBERS
      92             : };
      93             : 
      94             : 
      95           0 : enum
      96             : {
      97             :         // Property IDs
      98             :         kVector_x,
      99             :         kVector_y,
     100             :         kVector_z
     101             : };
     102             : 
     103             : 
     104           0 : static JSPropertySpec sVectorProperties[] =
     105             : {
     106             :         // JS name                                      ID                                                      flags
     107             :         { "x",                                                kVector_x,                                      OOJS_PROP_READWRITE_CB },
     108             :         { "y",                                                kVector_y,                                      OOJS_PROP_READWRITE_CB },
     109             :         { "z",                                                kVector_z,                                      OOJS_PROP_READWRITE_CB },
     110             :         { 0 }
     111             : };
     112             : 
     113             : 
     114           0 : static JSFunctionSpec sVectorMethods[] =
     115             : {
     116             :         // JS name                                      Function                                        min args
     117             :         { "toSource",                         VectorToSource,                         0, },
     118             :         { "toString",                         VectorToString,                         0, },
     119             :         { "add",                                      VectorAdd,                                      1, },
     120             :         { "angleTo",                          VectorAngleTo,                          1, },
     121             :         { "cross",                                    VectorCross,                            1, },
     122             :         { "direction",                                VectorDirection,                        0, },
     123             :         { "distanceTo",                               VectorDistanceTo,                       1, },
     124             :         { "dot",                                      VectorDot,                                      1, },
     125             :         { "fromCoordinateSystem",     VectorFromCoordinateSystem,     1, },
     126             :         { "magnitude",                                VectorMagnitude,                        0, },
     127             :         { "multiply",                         VectorMultiply,                         1, },
     128             :         { "rotateBy",                         VectorRotateBy,                         1, },
     129             :         { "rotationTo",                               VectorRotationTo,                       1, },
     130             :         { "squaredDistanceTo",                VectorSquaredDistanceTo,        1, },
     131             :         { "squaredMagnitude",         VectorSquaredMagnitude,         0, },
     132             :         { "subtract",                         VectorSubtract,                         1, },
     133             :         { "toArray",                          VectorToArray,                          0, },
     134             :         { "toCoordinateSystem",               VectorToCoordinateSystem,       1, },
     135             :         { "tripleProduct",                    VectorTripleProduct,            2, },
     136             :         { 0 }
     137             : };
     138             : 
     139             : 
     140           0 : static JSFunctionSpec sVectorStaticMethods[] =
     141             : {
     142             :         // JS name                                              Function                                                        min args
     143             :         { "interpolate",                              VectorStaticInterpolate,                        3, },
     144             :         { "random",                                           VectorStaticRandom,                                     0, },
     145             :         { "randomDirection",                  VectorStaticRandomDirection,            0, },
     146             :         { "randomDirectionAndLength", VectorStaticRandomDirectionAndLength, 0, },
     147             :         { 0 }
     148             : };
     149             : 
     150             : 
     151             : // *** Public ***
     152             : 
     153           0 : void InitOOJSVector(JSContext *context, JSObject *global)
     154             : {
     155             :         sVectorPrototype = JS_InitClass(context, global, NULL, &sVectorClass, VectorConstruct, 0, sVectorProperties, sVectorMethods, NULL, sVectorStaticMethods);
     156             : }
     157             : 
     158             : 
     159           0 : JSObject *JSVectorWithVector(JSContext *context, Vector vector)
     160             : {
     161             :         OOJS_PROFILE_ENTER
     162             :         
     163             :         JSObject                                *result = NULL;
     164             :         HPVector                                        *private = NULL;
     165             :         
     166             :         private = malloc(sizeof *private);
     167             :         if (EXPECT_NOT(private == NULL))  return NULL;
     168             :         
     169             :         *private = vectorToHPVector(vector);
     170             :         
     171             :         result = JS_NewObject(context, &sVectorClass, sVectorPrototype, NULL);
     172             :         if (result != NULL)
     173             :         {
     174             :                 if (EXPECT_NOT(!JS_SetPrivate(context, result, private)))  result = NULL;
     175             :         }
     176             :         
     177             :         if (EXPECT_NOT(result == NULL)) free(private);
     178             :         
     179             :         return result;
     180             :         
     181             :         OOJS_PROFILE_EXIT
     182             : }
     183             : 
     184             : 
     185           0 : BOOL VectorToJSValue(JSContext *context, Vector vector, jsval *outValue)
     186             : {
     187             :         OOJS_PROFILE_ENTER
     188             :         
     189             :         JSObject                                *object = NULL;
     190             :         
     191             :         assert(outValue != NULL);
     192             :         
     193             :         object = JSVectorWithVector(context, vector);
     194             :         if (EXPECT_NOT(object == NULL)) return NO;
     195             :         
     196             :         *outValue = OBJECT_TO_JSVAL(object);
     197             :         return YES;
     198             :         
     199             :         OOJS_PROFILE_EXIT
     200             : }
     201             : 
     202           0 : JSObject *JSVectorWithHPVector(JSContext *context, HPVector vector)
     203             : {
     204             :         OOJS_PROFILE_ENTER
     205             :         
     206             :         JSObject                                *result = NULL;
     207             :         HPVector                                        *private = NULL;
     208             :         
     209             :         private = malloc(sizeof *private);
     210             :         if (EXPECT_NOT(private == NULL))  return NULL;
     211             :         
     212             :         *private = vector;
     213             :         
     214             :         result = JS_NewObject(context, &sVectorClass, sVectorPrototype, NULL);
     215             :         if (result != NULL)
     216             :         {
     217             :                 if (EXPECT_NOT(!JS_SetPrivate(context, result, private)))  result = NULL;
     218             :         }
     219             :         
     220             :         if (EXPECT_NOT(result == NULL)) free(private);
     221             :         
     222             :         return result;
     223             :         
     224             :         OOJS_PROFILE_EXIT
     225             : }
     226             : 
     227             : 
     228           0 : BOOL HPVectorToJSValue(JSContext *context, HPVector vector, jsval *outValue)
     229             : {
     230             :         OOJS_PROFILE_ENTER
     231             :         
     232             :         JSObject                                *object = NULL;
     233             :         
     234             :         assert(outValue != NULL);
     235             :         
     236             :         object = JSVectorWithHPVector(context, vector);
     237             :         if (EXPECT_NOT(object == NULL)) return NO;
     238             :         
     239             :         *outValue = OBJECT_TO_JSVAL(object);
     240             :         return YES;
     241             :         
     242             :         OOJS_PROFILE_EXIT
     243             : }
     244             : 
     245             : 
     246           0 : BOOL NSPointToVectorJSValue(JSContext *context, NSPoint point, jsval *outValue)
     247             : {
     248             :         return VectorToJSValue(context, make_vector(point.x, point.y, 0), outValue);
     249             : }
     250             : 
     251             : 
     252           0 : BOOL JSValueToHPVector(JSContext *context, jsval value, HPVector *outVector)
     253             : {
     254             :         if (EXPECT_NOT(!JSVAL_IS_OBJECT(value)))  return NO;
     255             :         
     256             :         return JSObjectGetVector(context, JSVAL_TO_OBJECT(value), outVector);
     257             : }
     258             : 
     259           0 : BOOL JSValueToVector(JSContext *context, jsval value, Vector *outVector)
     260             : {
     261             :         if (EXPECT_NOT(!JSVAL_IS_OBJECT(value)))  return NO;
     262             :         HPVector tmp = kZeroHPVector;
     263             :         BOOL result = JSObjectGetVector(context, JSVAL_TO_OBJECT(value), &tmp);
     264             :         *outVector = HPVectorToVector(tmp);
     265             :         return result;
     266             : }
     267             : 
     268             : 
     269             : #if OO_DEBUG
     270             : 
     271             : typedef struct
     272             : {
     273             :         NSUInteger                      vectorCount;
     274             :         NSUInteger                      entityCount;
     275             :         NSUInteger                      arrayCount;
     276             :         NSUInteger                      protoCount;
     277             :         NSUInteger                      nullCount;
     278             :         NSUInteger                      failCount;
     279             : } VectorStatistics;
     280             : static VectorStatistics sVectorConversionStats;
     281             : 
     282             : 
     283             : @implementation PlayerEntity (JSVectorStatistics)
     284             : 
     285             : // :setM vectorStats PS.callObjC("reportJSVectorStatistics")
     286             : // :vectorStats
     287             : 
     288             : - (NSString *) reportJSVectorStatistics
     289             : {
     290             :         VectorStatistics *stats = &sVectorConversionStats;
     291             :         
     292             :         NSUInteger sum = stats->vectorCount + stats->entityCount + stats->arrayCount + stats->protoCount;
     293             :         double convFac = 100.0 / sum;
     294             :         if (sum == 0)  convFac = 0;
     295             :         
     296             :         return [NSString stringWithFormat:
     297             :                    @" vector-to-vector conversions: %lu (%g %%)\n"
     298             :                         " entity-to-vector conversions: %lu (%g %%)\n"
     299             :                         "  array-to-vector conversions: %lu (%g %%)\n"
     300             :                         "prototype-to-zero conversions: %lu (%g %%)\n"
     301             :                         "             null conversions: %lu (%g %%)\n"
     302             :                         "           failed conversions: %lu (%g %%)\n"
     303             :                         "                        total: %lu",
     304             :                         (long)stats->vectorCount, stats->vectorCount * convFac,
     305             :                         (long)stats->entityCount, stats->entityCount * convFac,
     306             :                         (long)stats->arrayCount, stats->arrayCount * convFac,
     307             :                         (long)stats->protoCount, stats->protoCount * convFac,
     308             :                         (long)stats->nullCount, stats->nullCount * convFac,
     309             :                         (long)stats->failCount, stats->failCount * convFac,
     310             :                         (long)sum];
     311             : }
     312             : 
     313             : 
     314             : - (void) clearJSVectorStatistics
     315             : {
     316             :         memset(&sVectorConversionStats, 0, sizeof sVectorConversionStats);
     317             : }
     318             : 
     319             : @end
     320             : 
     321             : #define COUNT(FIELD) do { sVectorConversionStats.FIELD++; } while (0)
     322             : 
     323             : #else
     324             : 
     325           0 : #define COUNT(FIELD) do {} while (0)
     326             : 
     327             : #endif
     328             : 
     329             : 
     330           0 : BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, HPVector *outVector)
     331             : {
     332             :         OOJS_PROFILE_ENTER
     333             :         
     334             :         assert(outVector != NULL);
     335             :         
     336             :         HPVector                                        *private = NULL;
     337             :         jsuint                                  arrayLength;
     338             :         jsval                                   arrayX, arrayY, arrayZ;
     339             :         jsdouble                                x, y, z;
     340             :         
     341             :         // vectorObj can legitimately be NULL, e.g. when JS_NULL is converted to a JSObject *.
     342             :         if (EXPECT_NOT(vectorObj == NULL))
     343             :         {
     344             :                 COUNT(nullCount);
     345             :                 return NO;
     346             :         }
     347             :         
     348             :         // If this is a (JS) Vector...
     349             :         private = JS_GetInstancePrivate(context, vectorObj, &sVectorClass, NULL);
     350             :         if (EXPECT(private != NULL))
     351             :         {
     352             :                 COUNT(vectorCount);
     353             :                 *outVector = *private;
     354             :                 return YES;
     355             :         }
     356             :         
     357             :         // If it's an array...
     358             :         if (EXPECT(JS_IsArrayObject(context, vectorObj)))
     359             :         {
     360             :                 // ...and it has exactly three elements...
     361             :                 if (JS_GetArrayLength(context, vectorObj, &arrayLength) && arrayLength == 3)
     362             :                 {
     363             :                         if (JS_LookupElement(context, vectorObj, 0, &arrayX) &&
     364             :                                 JS_LookupElement(context, vectorObj, 1, &arrayY) &&
     365             :                                 JS_LookupElement(context, vectorObj, 2, &arrayZ))
     366             :                         {
     367             :                                 // ...use the three numbers as [x, y, z]
     368             :                                 if (JS_ValueToNumber(context, arrayX, &x) &&
     369             :                                         JS_ValueToNumber(context, arrayY, &y) &&
     370             :                                         JS_ValueToNumber(context, arrayZ, &z))
     371             :                                 {
     372             :                                         COUNT(arrayCount);
     373             :                                         *outVector = make_HPvector(x, y, z);
     374             :                                         return YES;
     375             :                                 }
     376             :                         }
     377             :                 }
     378             :         }
     379             :         
     380             :         // If it's an entity, use its position.
     381             :         if (OOJSIsMemberOfSubclass(context, vectorObj, JSEntityClass()))
     382             :         {
     383             :                 COUNT(entityCount);
     384             :                 Entity *entity = [(id)JS_GetPrivate(context, vectorObj) weakRefUnderlyingObject];
     385             :                 *outVector = [entity position];
     386             :                 return YES;
     387             :         }
     388             :         
     389             :         /*
     390             :                 If it's actually a Vector3D but with no private field (this happens for
     391             :                 Vector3D.prototype)...
     392             :                 
     393             :                 NOTE: it would be prettier to do this at the top when we handle normal
     394             :                 Vector3Ds, but it's a rare case which should be kept off the fast path.
     395             :         */
     396             :         if (JS_InstanceOf(context, vectorObj, &sVectorClass, NULL))
     397             :         {
     398             :                 COUNT(protoCount);
     399             :                 *outVector = kZeroHPVector;
     400             :                 return YES;
     401             :         }
     402             :         
     403             :         COUNT(failCount);
     404             :         return NO;
     405             :         
     406             :         OOJS_PROFILE_EXIT
     407             : }
     408             : 
     409             : 
     410           0 : static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, HPVector *outVector, NSString *method)
     411             : {
     412             :         if (EXPECT(JSObjectGetVector(context, vectorObj, outVector)))  return YES;
     413             :         
     414             :         jsval arg = OBJECT_TO_JSVAL(vectorObj);
     415             :         OOJSReportBadArguments(context, @"Vector3D", method, 1, &arg, @"Invalid target object", @"Vector3D");
     416             :         return NO;
     417             : }
     418             : 
     419             : 
     420           0 : BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector)
     421             : {
     422             :         return JSVectorSetHPVector(context,vectorObj,vectorToHPVector(vector));
     423             : }
     424             : 
     425             : 
     426           0 : BOOL JSVectorSetHPVector(JSContext *context, JSObject *vectorObj, HPVector vector)
     427             : {
     428             :         OOJS_PROFILE_ENTER
     429             :         
     430             :         HPVector                                        *private = NULL;
     431             :         
     432             :         if (EXPECT_NOT(vectorObj == NULL))  return NO;
     433             :         
     434             :         private = JS_GetInstancePrivate(context, vectorObj, &sVectorClass, NULL);
     435             :         if (private != NULL)    // If this is a (JS) Vector...
     436             :         {
     437             :                 *private = vector;
     438             :                 return YES;
     439             :         }
     440             :         
     441             :         if (JS_InstanceOf(context, vectorObj, &sVectorClass, NULL))
     442             :         {
     443             :                 // Silently fail for the prototype.
     444             :                 return YES;
     445             :         }
     446             :         
     447             :         return NO;
     448             :         
     449             :         OOJS_PROFILE_EXIT
     450             : }
     451             : 
     452             : 
     453           0 : static BOOL VectorFromArgumentListNoErrorInternal(JSContext *context, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed, BOOL permitNumberList)
     454             : {
     455             :         OOJS_PROFILE_ENTER
     456             :         
     457             :         double                          x, y, z;
     458             :         
     459             :         if (EXPECT_NOT(argc == 0))  return NO;
     460             :         assert(argv != NULL && outVector != NULL);
     461             :         
     462             :         if (outConsumed != NULL)  *outConsumed = 0;
     463             :         
     464             :         // Is first object a vector, array or entity?
     465             :         if (JSVAL_IS_OBJECT(argv[0]))
     466             :         {
     467             :                 if (JSObjectGetVector(context, JSVAL_TO_OBJECT(argv[0]), outVector))
     468             :                 {
     469             :                         if (outConsumed != NULL)  *outConsumed = 1;
     470             :                         return YES;
     471             :                 }
     472             :         }
     473             :         
     474             :         if (!permitNumberList)  return NO;
     475             :         
     476             :         // As a special case for VectorConstruct(), look for three numbers.
     477             :         if (argc < 3)  return NO;
     478             :         
     479             :         // Given a string, JS_ValueToNumber() returns YES but provides a NaN number.
     480             :         if (EXPECT_NOT(!JS_ValueToNumber(context, argv[0], &x) || isnan(x)))  return NO;
     481             :         if (EXPECT_NOT(!JS_ValueToNumber(context, argv[1], &y) || isnan(y)))  return NO;
     482             :         if (EXPECT_NOT(!JS_ValueToNumber(context, argv[2], &z) || isnan(z)))  return NO;
     483             :         
     484             :         // We got our three numbers.
     485             :         *outVector = make_HPvector(x, y, z);
     486             :         if (outConsumed != NULL)  *outConsumed = 3;
     487             :         
     488             :         return YES;
     489             :         
     490             :         OOJS_PROFILE_EXIT
     491             : }
     492             : 
     493             : 
     494             : // EMMSTRAN: remove outConsumed, since it can only be 1 except in failure (constructor is an exception, but it uses VectorFromArgumentListNoErrorInternal() directly).
     495           0 : BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed)
     496             : {
     497             :         if (VectorFromArgumentListNoErrorInternal(context, argc, argv, outVector, outConsumed, NO))  return YES;
     498             :         else
     499             :         {
     500             :                 OOJSReportBadArguments(context, scriptClass, function, argc, argv,
     501             :                                                            @"Could not construct vector from parameters",
     502             :                                                            @"Vector, Entity or array of three numbers");
     503             :                 return NO;
     504             :         }
     505             : }
     506             : 
     507             : 
     508           0 : BOOL VectorFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed)
     509             : {
     510             :         return VectorFromArgumentListNoErrorInternal(context, argc, argv, outVector, outConsumed, NO);
     511             : }
     512             : 
     513             : 
     514             : // *** Implementation stuff ***
     515             : 
     516           0 : static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
     517             : {
     518             :         if (!JSID_IS_INT(propID))  return YES;
     519             :         
     520             :         OOJS_PROFILE_ENTER
     521             :         
     522             :         HPVector                                vector;
     523             :         OOHPScalar                              fValue;
     524             :         
     525             :         if (EXPECT_NOT(!JSObjectGetVector(context, this, &vector)))  return NO;
     526             :         
     527             :         switch (JSID_TO_INT(propID))
     528             :         {
     529             :                 case kVector_x:
     530             :                         fValue = vector.x;
     531             :                         break;
     532             :                 
     533             :                 case kVector_y:
     534             :                         fValue = vector.y;
     535             :                         break;
     536             :                 
     537             :                 case kVector_z:
     538             :                         fValue = vector.z;
     539             :                         break;
     540             :                 
     541             :                 default:
     542             :                         OOJSReportBadPropertySelector(context, this, propID, sVectorProperties);
     543             :                         return NO;
     544             :         }
     545             :         
     546             :         return JS_NewNumberValue(context, fValue, value);
     547             :         
     548             :         OOJS_PROFILE_EXIT
     549             : }
     550             : 
     551             : 
     552           0 : static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
     553             : {
     554             :         if (!JSID_IS_INT(propID))  return YES;
     555             :         
     556             :         OOJS_PROFILE_ENTER
     557             :         
     558             :         HPVector                                vector;
     559             :         jsdouble                        dval;
     560             :         
     561             :         if (EXPECT_NOT(!JSObjectGetVector(context, this, &vector)))  return NO;
     562             :         if (EXPECT_NOT(!JS_ValueToNumber(context, *value, &dval)))
     563             :         {
     564             :                 OOJSReportBadPropertyValue(context, this, propID, sVectorProperties, *value);
     565             :                 return NO;
     566             :         }
     567             :         
     568             :         switch (JSID_TO_INT(propID))
     569             :         {
     570             :                 case kVector_x:
     571             :                         vector.x = dval;
     572             :                         break;
     573             :                 
     574             :                 case kVector_y:
     575             :                         vector.y = dval;
     576             :                         break;
     577             :                 
     578             :                 case kVector_z:
     579             :                         vector.z = dval;
     580             :                         break;
     581             :                 
     582             :                 default:
     583             :                         OOJSReportBadPropertySelector(context, this, propID, sVectorProperties);
     584             :                         return NO;
     585             :         }
     586             :         
     587             :         return JSVectorSetHPVector(context, this, vector);
     588             :         
     589             :         OOJS_PROFILE_EXIT
     590             : }
     591             : 
     592             : 
     593           0 : static void VectorFinalize(JSContext *context, JSObject *this)
     594             : {
     595             :         OOJS_PROFILE_ENTER
     596             :         
     597             :         Vector                                  *private = NULL;
     598             :         
     599             :         private = JS_GetInstancePrivate(context, this, &sVectorClass, NULL);
     600             :         if (private != NULL)
     601             :         {
     602             :                 free(private);
     603             :         }
     604             :         
     605             :         OOJS_PROFILE_EXIT_VOID
     606             : }
     607             : 
     608             : 
     609           0 : static JSBool VectorConstruct(JSContext *context, uintN argc, jsval *vp)
     610             : {
     611             :         OOJS_PROFILE_ENTER
     612             :         
     613             :         HPVector                                        vector = kZeroHPVector;
     614             :         HPVector                                        *private = NULL;
     615             :         JSObject                                *this = NULL;
     616             :         
     617             :         private = malloc(sizeof *private);
     618             :         if (EXPECT_NOT(private == NULL))  return NO;
     619             :         
     620             :         this = JS_NewObject(context, &sVectorClass, NULL, NULL);
     621             :         if (EXPECT_NOT(this == NULL))  return NO;
     622             :         
     623             :         if (argc != 0)
     624             :         {
     625             :                 if (EXPECT_NOT(!VectorFromArgumentListNoErrorInternal(context, argc, OOJS_ARGV, &vector, NULL, YES)))
     626             :                 {
     627             :                         free(private);
     628             :                         OOJSReportBadArguments(context, NULL, NULL, argc, OOJS_ARGV,
     629             :                                                                    @"Could not construct vector from parameters",
     630             :                                                                    @"Vector, Entity or array of three numbers");
     631             :                         return NO;
     632             :                 }
     633             :         }
     634             :         
     635             :         *private = vector;
     636             :         
     637             :         if (EXPECT_NOT(!JS_SetPrivate(context, this, private)))
     638             :         {
     639             :                 free(private);
     640             :                 return NO;
     641             :         }
     642             :         
     643             :         OOJS_RETURN_JSOBJECT(this);
     644             :         
     645             :         OOJS_PROFILE_EXIT
     646             : }
     647             : 
     648             : 
     649             : // *** Methods ***
     650             : 
     651             : // toString() : String
     652           0 : static JSBool VectorToString(JSContext *context, uintN argc, jsval *vp)
     653             : {
     654             :         OOJS_NATIVE_ENTER(context)
     655             :         
     656             :         HPVector                                        thisv;
     657             :         
     658             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"toString"))) return NO;
     659             :         
     660             :         OOJS_RETURN_OBJECT(HPVectorDescription(thisv));
     661             :         
     662             :         OOJS_NATIVE_EXIT
     663             : }
     664             : 
     665             : 
     666             : // toSource() : String
     667           0 : static JSBool VectorToSource(JSContext *context, uintN argc, jsval *vp)
     668             : {
     669             :         OOJS_NATIVE_ENTER(context)
     670             :         
     671             :         HPVector                                        thisv;
     672             :         
     673             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"toSource"))) return NO;
     674             :         
     675             :         NSString *str = [NSString stringWithFormat:@"Vector3D(%g, %g, %g)", thisv.x, thisv.y, thisv.z];
     676             :         OOJS_RETURN_OBJECT(str);
     677             :         
     678             :         OOJS_NATIVE_EXIT
     679             : }
     680             : 
     681             : 
     682             : // add(v : vectorExpression) : Vector3D
     683           0 : static JSBool VectorAdd(JSContext *context, uintN argc, jsval *vp)
     684             : {
     685             :         OOJS_PROFILE_ENTER
     686             :         
     687             :         HPVector                                        thisv, thatv, result;
     688             :         
     689             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"add"))) return NO;
     690             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"add", argc, OOJS_ARGV, &thatv, NULL)))  return NO;
     691             :         
     692             :         result = HPvector_add(thisv, thatv);
     693             :         
     694             :         OOJS_RETURN_HPVECTOR(result);
     695             :         
     696             :         OOJS_PROFILE_EXIT
     697             : }
     698             : 
     699             : 
     700             : // subtract(v : vectorExpression) : Vector3D
     701           0 : static JSBool VectorSubtract(JSContext *context, uintN argc, jsval *vp)
     702             : {
     703             :         OOJS_PROFILE_ENTER
     704             :         
     705             :         HPVector                                        thisv, thatv, result;
     706             :         
     707             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"subtract"))) return NO;
     708             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"subtract", argc, OOJS_ARGV, &thatv, NULL)))  return NO;
     709             :         
     710             :         result = HPvector_subtract(thisv, thatv);
     711             :         
     712             :         OOJS_RETURN_HPVECTOR(result);
     713             :         
     714             :         OOJS_PROFILE_EXIT
     715             : }
     716             : 
     717             : 
     718             : // distanceTo(v : vectorExpression) : Number
     719           0 : static JSBool VectorDistanceTo(JSContext *context, uintN argc, jsval *vp)
     720             : {
     721             :         OOJS_PROFILE_ENTER
     722             :         
     723             :         HPVector                                        thisv, thatv;
     724             :         double                                          result;
     725             :         
     726             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"distanceTo"))) return NO;
     727             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"distanceTo", argc, OOJS_ARGV, &thatv, NULL)))  return NO;
     728             :         
     729             :         result = HPdistance(thisv, thatv);
     730             :         
     731             :         OOJS_RETURN_DOUBLE(result);
     732             :         
     733             :         OOJS_PROFILE_EXIT
     734             : }
     735             : 
     736             : 
     737             : // squaredDistanceTo(v : vectorExpression) : Number
     738           0 : static JSBool VectorSquaredDistanceTo(JSContext *context, uintN argc, jsval *vp)
     739             : {
     740             :         OOJS_PROFILE_ENTER
     741             :         
     742             :         HPVector                                        thisv, thatv;
     743             :         double                                          result;
     744             :         
     745             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"squaredDistanceTo"))) return NO;
     746             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"squaredDistanceTo", argc, OOJS_ARGV, &thatv, NULL)))  return NO;
     747             :         
     748             :         result = HPdistance2(thisv, thatv);
     749             :         
     750             :         OOJS_RETURN_DOUBLE(result);
     751             :         
     752             :         OOJS_PROFILE_EXIT
     753             : }
     754             : 
     755             : 
     756             : // multiply(n : Number) : Vector3D
     757           0 : static JSBool VectorMultiply(JSContext *context, uintN argc, jsval *vp)
     758             : {
     759             :         OOJS_PROFILE_ENTER
     760             :         
     761             :         HPVector                                        thisv, result;
     762             :         double                                          scalar;
     763             :         
     764             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"multiply"))) return NO;
     765             :         if (EXPECT_NOT(!OOJSArgumentListGetNumber(context, @"Vector3D", @"multiply", argc, OOJS_ARGV, &scalar, NULL)))  return NO;
     766             :         
     767             :         result = HPvector_multiply_scalar(thisv, scalar);
     768             :         
     769             :         OOJS_RETURN_HPVECTOR(result);
     770             :         
     771             :         OOJS_PROFILE_EXIT
     772             : }
     773             : 
     774             : 
     775             : // dot(v : vectorExpression) : Number
     776           0 : static JSBool VectorDot(JSContext *context, uintN argc, jsval *vp)
     777             : {
     778             :         OOJS_PROFILE_ENTER
     779             :         
     780             :         HPVector                                        thisv, thatv;
     781             :         double                                          result;
     782             :         
     783             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"dot"))) return NO;
     784             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"dot", argc, OOJS_ARGV, &thatv, NULL)))  return NO;
     785             :         
     786             :         result = HPdot_product(thisv, thatv);
     787             :         
     788             :         OOJS_RETURN_DOUBLE(result);
     789             :         
     790             :         OOJS_PROFILE_EXIT
     791             : }
     792             : 
     793             : 
     794             : // angleTo(v : vectorExpression) : Number
     795           0 : static JSBool VectorAngleTo(JSContext *context, uintN argc, jsval *vp)
     796             : {
     797             :         OOJS_PROFILE_ENTER
     798             :         
     799             :         HPVector                                        thisv, thatv;
     800             :         double                                          result;
     801             :         
     802             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"angleTo"))) return NO;
     803             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"angleTo", argc, OOJS_ARGV, &thatv, NULL)))  return NO;
     804             :         
     805             :         result = HPdot_product(HPvector_normal(thisv), HPvector_normal(thatv));
     806             :         if (result > 1.0) result = 1.0;
     807             :         if (result < -1.0) result = -1.0;
     808             :         // for identical vectors the dot_product sometimes returns a value > 1.0 because of rounding errors, resulting
     809             :         // in an undefined result for the acos.
     810             :         result = acos(result);
     811             :         
     812             :         OOJS_RETURN_DOUBLE(result);
     813             :         
     814             :         OOJS_PROFILE_EXIT
     815             : }
     816             : 
     817             : 
     818             : // cross(v : vectorExpression) : Vector3D
     819           0 : static JSBool VectorCross(JSContext *context, uintN argc, jsval *vp)
     820             : {
     821             :         OOJS_PROFILE_ENTER
     822             :         
     823             :         HPVector                                        thisv, thatv, result;
     824             :         
     825             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"cross"))) return NO;
     826             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"cross", argc, OOJS_ARGV, &thatv, NULL)))  return NO;
     827             :         
     828             :         result = HPtrue_cross_product(thisv, thatv);
     829             :         
     830             :         OOJS_RETURN_HPVECTOR(result);
     831             :         
     832             :         OOJS_PROFILE_EXIT
     833             : }
     834             : 
     835             : 
     836             : // tripleProduct(v : vectorExpression, u : vectorExpression) : Number
     837           0 : static JSBool VectorTripleProduct(JSContext *context, uintN argc, jsval *vp)
     838             : {
     839             :         OOJS_PROFILE_ENTER
     840             :         
     841             :         HPVector                                        thisv, thatv, theotherv;
     842             :         double                                          result;
     843             :         uintN                                           consumed;
     844             :         jsval                                           *argv = OOJS_ARGV;
     845             :         
     846             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"tripleProduct"))) return NO;
     847             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"tripleProduct", argc, argv, &thatv, &consumed)))  return NO;
     848             :         argc -= consumed;
     849             :         argv += consumed;
     850             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"tripleProduct", argc, argv, &theotherv, NULL)))  return NO;
     851             :         
     852             :         result = HPtriple_product(thisv, thatv, theotherv);
     853             :         
     854             :         OOJS_RETURN_DOUBLE(result);
     855             :         
     856             :         OOJS_PROFILE_EXIT
     857             : }
     858             : 
     859             : 
     860             : // direction() : Vector3D
     861           0 : static JSBool VectorDirection(JSContext *context, uintN argc, jsval *vp)
     862             : {
     863             :         OOJS_PROFILE_ENTER
     864             :         
     865             :         HPVector                                        thisv, result;
     866             :         
     867             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"direction"))) return NO;
     868             :         
     869             :         result = HPvector_normal(thisv);
     870             :         
     871             :         OOJS_RETURN_HPVECTOR(result);
     872             :         
     873             :         OOJS_PROFILE_EXIT
     874             : }
     875             : 
     876             : 
     877             : // magnitude() : Number
     878           0 : static JSBool VectorMagnitude(JSContext *context, uintN argc, jsval *vp)
     879             : {
     880             :         OOJS_PROFILE_ENTER
     881             :         
     882             :         HPVector                                        thisv;
     883             :         double                                          result;
     884             :         
     885             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"magnitude"))) return NO;
     886             :         
     887             :         result = HPmagnitude(thisv);
     888             :         
     889             :         OOJS_RETURN_DOUBLE(result);
     890             :         
     891             :         OOJS_PROFILE_EXIT
     892             : }
     893             : 
     894             : 
     895             : // squaredMagnitude() : Number
     896           0 : static JSBool VectorSquaredMagnitude(JSContext *context, uintN argc, jsval *vp)
     897             : {
     898             :         OOJS_PROFILE_ENTER
     899             :         
     900             :         HPVector                                        thisv;
     901             :         double                                          result;
     902             :         
     903             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"squaredMagnitude"))) return NO;
     904             :         
     905             :         result = HPmagnitude2(thisv);
     906             :         
     907             :         OOJS_RETURN_DOUBLE(result);
     908             :         
     909             :         OOJS_PROFILE_EXIT
     910             : }
     911             : 
     912             : 
     913             : // rotationTo(v : vectorExpression [, limit : Number]) : Quaternion
     914           0 : static JSBool VectorRotationTo(JSContext *context, uintN argc, jsval *vp)
     915             : {
     916             :         OOJS_PROFILE_ENTER
     917             :         
     918             :         HPVector                                        thisv, thatv;
     919             :         double                                  limit;
     920             :         BOOL                                    gotLimit;
     921             :         Quaternion                              result;
     922             :         uintN                                   consumed;
     923             :         jsval                                   *argv = OOJS_ARGV;
     924             :         
     925             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"rotationTo"))) return NO;
     926             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"rotationTo", argc, OOJS_ARGV, &thatv, &consumed)))  return NO;
     927             :         
     928             :         argc -= consumed;
     929             :         argv += consumed;
     930             :         if (argc != 0)  // limit parameter is optional.
     931             :         {
     932             :                 if (EXPECT_NOT(!OOJSArgumentListGetNumber(context, @"Vector3D", @"rotationTo", argc, argv, &limit, NULL)))  return NO;
     933             :                 gotLimit = YES;
     934             :         }
     935             :         else gotLimit = NO;
     936             :         
     937             :         if (gotLimit)  result = quaternion_limited_rotation_between(HPVectorToVector(thisv), HPVectorToVector(thatv), limit);
     938             :         else  result = quaternion_rotation_between(HPVectorToVector(thisv), HPVectorToVector(thatv));
     939             :         
     940             :         OOJS_RETURN_QUATERNION(result);
     941             :         
     942             :         OOJS_PROFILE_EXIT
     943             : }
     944             : 
     945             : 
     946             : // rotateBy(q : quaternionExpression) : Vector3D
     947           0 : static JSBool VectorRotateBy(JSContext *context, uintN argc, jsval *vp)
     948             : {
     949             :         OOJS_PROFILE_ENTER
     950             :         
     951             :         HPVector                                        thisv, result;
     952             :         Quaternion                              q;
     953             :         
     954             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"rotateBy"))) return NO;
     955             :         if (EXPECT_NOT(!QuaternionFromArgumentList(context, @"Vector3D", @"rotateBy", argc, OOJS_ARGV, &q, NULL)))  return NO;
     956             :         
     957             :         result = quaternion_rotate_HPvector(q, thisv);
     958             :         
     959             :         OOJS_RETURN_HPVECTOR(result);
     960             :         
     961             :         OOJS_PROFILE_EXIT
     962             : }
     963             : 
     964             : 
     965             : // toArray() : Array
     966           0 : static JSBool VectorToArray(JSContext *context, uintN argc, jsval *vp)
     967             : {
     968             :         OOJS_PROFILE_ENTER
     969             :         
     970             :         HPVector                                        thisv;
     971             :         JSObject                                *result = NULL;
     972             :         jsval                                   nVal;
     973             :         
     974             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"toArray"))) return NO;
     975             :         
     976             :         result = JS_NewArrayObject(context, 0, NULL);
     977             :         if (result != NULL)
     978             :         {
     979             :                 // We do this at the top because the return value slot is a GC root.
     980             :                 OOJS_SET_RVAL(OBJECT_TO_JSVAL(result));
     981             :                 
     982             :                 if (JS_NewNumberValue(context, thisv.x, &nVal) && JS_SetElement(context, result, 0, &nVal) &&
     983             :                         JS_NewNumberValue(context, thisv.y, &nVal) && JS_SetElement(context, result, 1, &nVal) &&
     984             :                         JS_NewNumberValue(context, thisv.z, &nVal) && JS_SetElement(context, result, 2, &nVal))
     985             :                 {
     986             :                         return YES;
     987             :                 }
     988             :                 // If we get here, the conversion and stuffing in the previous condition failed.
     989             :                 OOJS_SET_RVAL(JSVAL_VOID);
     990             :         }
     991             :         
     992             :         return YES;
     993             :         
     994             :         OOJS_PROFILE_EXIT
     995             : }
     996             : 
     997             : 
     998             : // toCoordinateSystem(coordScheme : String)
     999           0 : static JSBool VectorToCoordinateSystem(JSContext *context, uintN argc, jsval *vp)
    1000             : {
    1001             :         OOJS_NATIVE_ENTER(context)
    1002             :         
    1003             :         HPVector                                thisv;
    1004             :         NSString                        *coordScheme = nil;
    1005             :         HPVector                                result;
    1006             :         
    1007             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"toCoordinateSystem"))) return NO;
    1008             :         
    1009             :         if (EXPECT_NOT(argc < 1 ||
    1010             :                                    (coordScheme = OOStringFromJSValue(context, OOJS_ARGV[0])) == nil))
    1011             :         {
    1012             :                 OOJSReportBadArguments(context, @"Vector3D", @"toCoordinateSystem", MIN(argc, 1U), OOJS_ARGV, nil, @"coordinate system");
    1013             :                 return NO;
    1014             :         }
    1015             :         
    1016             :         OOJS_BEGIN_FULL_NATIVE(context)
    1017             :         result = [UNIVERSE legacyPositionFrom:thisv asCoordinateSystem:coordScheme];
    1018             :         OOJS_END_FULL_NATIVE
    1019             :         
    1020             :         OOJS_RETURN_HPVECTOR(result);
    1021             :         
    1022             :         OOJS_NATIVE_EXIT
    1023             : }
    1024             : 
    1025             : 
    1026             : // fromCoordinateSystem(coordScheme : String)
    1027           0 : static JSBool VectorFromCoordinateSystem(JSContext *context, uintN argc, jsval *vp)
    1028             : {
    1029             :         OOJS_NATIVE_ENTER(context)
    1030             :         
    1031             :         HPVector                                thisv;
    1032             :         NSString                        *coordScheme = nil;
    1033             :         HPVector                                result;
    1034             :         
    1035             :         if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"fromCoordinateSystem"))) return NO;
    1036             :         
    1037             :         if (EXPECT_NOT(argc < 1 ||
    1038             :                                    (coordScheme = OOStringFromJSValue(context, OOJS_ARGV[0])) == nil))
    1039             :         {
    1040             :                 OOJSReportBadArguments(context, @"Vector3D", @"fromCoordinateSystem", MIN(argc, 1U), OOJS_ARGV, nil, @"coordinate system");
    1041             :                 return NO;
    1042             :         }
    1043             :         
    1044             :         OOJS_BEGIN_FULL_NATIVE(context)
    1045             :         NSString *arg = [NSString stringWithFormat:@"%@ %f %f %f", coordScheme, thisv.x, thisv.y, thisv.z];
    1046             :         result = [UNIVERSE coordinatesFromCoordinateSystemString:arg];
    1047             :         OOJS_END_FULL_NATIVE
    1048             :         
    1049             :         OOJS_RETURN_HPVECTOR(result);
    1050             :         
    1051             :         OOJS_NATIVE_EXIT
    1052             : }
    1053             : 
    1054             : 
    1055             : // *** Static methods ***
    1056             : 
    1057             : 
    1058             : // interpolate(v : Vector3D, u : Vector3D, alpha : Number) : Vector3D
    1059           0 : static JSBool VectorStaticInterpolate(JSContext *context, uintN argc, jsval *vp)
    1060             : {
    1061             :         OOJS_PROFILE_ENTER
    1062             :         
    1063             :         HPVector                                        av, bv;
    1064             :         double                                  interp;
    1065             :         HPVector                                        result;
    1066             :         uintN                                   consumed;
    1067             :         uintN                                   inArgc = argc;
    1068             :         jsval                                   *argv = OOJS_ARGV;
    1069             :         jsval                                   *inArgv = argv;
    1070             :         
    1071             :         if (EXPECT_NOT(argc < 3))  goto INSUFFICIENT_ARGUMENTS;
    1072             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"interpolate", argc, argv, &av, &consumed)))  return NO;
    1073             :         argc -= consumed;
    1074             :         argv += consumed;
    1075             :         if (EXPECT_NOT(argc < 2))  goto INSUFFICIENT_ARGUMENTS;
    1076             :         if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"interpolate", argc, argv, &bv, &consumed)))  return NO;
    1077             :         argc -= consumed;
    1078             :         argv += consumed;
    1079             :         if (EXPECT_NOT(argc < 1))  goto INSUFFICIENT_ARGUMENTS;
    1080             :         if (EXPECT_NOT(!OOJSArgumentListGetNumber(context, @"Vector3D", @"interpolate", argc, argv, &interp, NULL)))  return NO;
    1081             :         
    1082             :         result = OOHPVectorInterpolate(av, bv, interp);
    1083             :         
    1084             :         OOJS_RETURN_HPVECTOR(result);
    1085             :         
    1086             : INSUFFICIENT_ARGUMENTS:
    1087             :         OOJSReportBadArguments(context, @"Vector3D", @"interpolate", inArgc, inArgv, 
    1088             :                                                                    @"Insufficient parameters",
    1089             :                                                                    @"vector expression, vector expression and number");
    1090             :         return NO;
    1091             :         
    1092             :         OOJS_PROFILE_EXIT
    1093             : }
    1094             : 
    1095             : 
    1096             : // random([maxLength : Number]) : Vector3D
    1097           0 : static JSBool VectorStaticRandom(JSContext *context, uintN argc, jsval *vp)
    1098             : {
    1099             :         OOJS_PROFILE_ENTER
    1100             :         
    1101             :         double                                  maxLength;
    1102             :         
    1103             :         if (argc == 0 || !OOJSArgumentListGetNumberNoError(context, argc, OOJS_ARGV, &maxLength, NULL))  maxLength = 1.0;
    1104             :         
    1105             :         OOJS_RETURN_HPVECTOR(OOHPVectorRandomSpatial(maxLength));
    1106             :         
    1107             :         OOJS_PROFILE_EXIT
    1108             : }
    1109             : 
    1110             : 
    1111             : // randomDirection([scale : Number]) : Vector3D
    1112           0 : static JSBool VectorStaticRandomDirection(JSContext *context, uintN argc, jsval *vp)
    1113             : {
    1114             :         OOJS_PROFILE_ENTER
    1115             :         
    1116             :         double                                  scale;
    1117             :         
    1118             :         if (argc == 0 || !OOJSArgumentListGetNumberNoError(context, argc, OOJS_ARGV, &scale, NULL))  scale = 1.0;
    1119             :         
    1120             :         OOJS_RETURN_HPVECTOR(HPvector_multiply_scalar(OORandomUnitHPVector(), scale));
    1121             :         
    1122             :         OOJS_PROFILE_EXIT
    1123             : }
    1124             : 
    1125             : 
    1126             : // randomDirectionAndLength([maxLength : Number]) : Vector3D
    1127           0 : static JSBool VectorStaticRandomDirectionAndLength(JSContext *context, uintN argc, jsval *vp)
    1128             : {
    1129             :         OOJS_PROFILE_ENTER
    1130             :         
    1131             :         double                                  maxLength;
    1132             :         
    1133             :         if (argc == 0 || !OOJSArgumentListGetNumberNoError(context, argc, OOJS_ARGV, &maxLength, NULL))  maxLength = 1.0;
    1134             :         
    1135             :         OOJS_RETURN_HPVECTOR(OOHPVectorRandomRadial(maxLength));
    1136             :         
    1137             :         OOJS_PROFILE_EXIT
    1138             : }
    1139             : 
    1140             : 

Generated by: LCOV version 1.14