29#import <GNUstepBase/GSObjCRuntime.h>
31#import <objc/objc-runtime.h>
46static JSBool
QuaternionSetProperty(JSContext *context, JSObject *
this, jsid propID, JSBool strict, jsval *value);
54static JSBool
QuaternionDot(JSContext *context, uintN argc, jsval *vp);
83 JSCLASS_NO_OPTIONAL_MEMBERS
149 JSObject *result = NULL;
150 Quaternion *
private = NULL;
152 private = malloc(
sizeof *
private);
155 *
private = quaternion;
160 if (!JS_SetPrivate(context, result,
private)) result = NULL;
163 if (
EXPECT_NOT(result == NULL)) free(
private);
175 JSObject *
object = NULL;
177 assert(outValue != NULL);
182 *outValue = OBJECT_TO_JSVAL(
object);
191 if (
EXPECT_NOT(!JSVAL_IS_OBJECT(value)))
return NO;
201 NSUInteger quatCount;
202 NSUInteger entityCount;
203 NSUInteger arrayCount;
204 NSUInteger protoCount;
205 NSUInteger nullCount;
206 NSUInteger failCount;
207} QuaternionStatistics;
208static QuaternionStatistics sQuaternionConversionStats;
211@implementation PlayerEntity (JSQuaternionStatistics)
216- (NSString *) reportJSQuaternionStatistics
218 QuaternionStatistics *stats = &sQuaternionConversionStats;
220 NSUInteger sum = stats->quatCount + stats->entityCount + stats->arrayCount + stats->protoCount;
221 double convFac = 100.0 / sum;
223 return [NSString stringWithFormat:
224 @"quaternion-to-quaternion conversions: %lu (%g %%)\n"
225 " entity-to-quaternion conversions: %lu (%g %%)\n"
226 " array-to-quaternion conversions: %lu (%g %%)\n"
227 " prototype-to-zero conversions: %lu (%g %%)\n"
228 " null conversions: %lu (%g %%)\n"
229 " failed conversions: %lu (%g %%)\n"
231 (long)stats->quatCount, stats->quatCount * convFac,
232 (long)stats->entityCount, stats->entityCount * convFac,
233 (long)stats->arrayCount, stats->arrayCount * convFac,
234 (long)stats->protoCount, stats->protoCount * convFac,
235 (long)stats->nullCount, stats->nullCount * convFac,
236 (long)stats->failCount, stats->failCount * convFac,
241- (void) clearJSQuaternionStatistics
243 memset(&sQuaternionConversionStats, 0,
sizeof sQuaternionConversionStats);
248#define COUNT(FIELD) do { sQuaternionConversionStats.FIELD++; } while (0)
252#define COUNT(FIELD) do {} while (0)
261 assert(outQuaternion != NULL);
263 Quaternion *
private = NULL;
265 jsval arrayW, arrayX, arrayY, arrayZ;
276 private = JS_GetInstancePrivate(context, quaternionObj, &
sQuaternionClass, NULL);
277 if (
EXPECT(
private != NULL))
280 *outQuaternion = *
private;
285 if (
EXPECT(JS_IsArrayObject(context, quaternionObj)))
288 if (JS_GetArrayLength(context, quaternionObj, &arrayLength) && arrayLength == 4)
290 if (JS_LookupElement(context, quaternionObj, 0, &arrayW) &&
291 JS_LookupElement(context, quaternionObj, 1, &arrayX) &&
292 JS_LookupElement(context, quaternionObj, 2, &arrayY) &&
293 JS_LookupElement(context, quaternionObj, 3, &arrayZ))
296 if (!JS_ValueToNumber(context, arrayW, &dVal))
return NO;
297 outQuaternion->w = dVal;
298 if (!JS_ValueToNumber(context, arrayX, &dVal))
return NO;
299 outQuaternion->x = dVal;
300 if (!JS_ValueToNumber(context, arrayY, &dVal))
return NO;
301 outQuaternion->y = dVal;
302 if (!JS_ValueToNumber(context, arrayZ, &dVal))
return NO;
303 outQuaternion->z = dVal;
315 Entity *entity = JS_GetPrivate(context, quaternionObj);
341static BOOL
GetThisQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion *outQuaternion, NSString *method)
345 jsval arg = OBJECT_TO_JSVAL(quaternionObj);
355 Quaternion *
private = NULL;
357 assert(quaternionObj != NULL);
359 private = JS_GetInstancePrivate(context, quaternionObj, &
sQuaternionClass, NULL);
362 *
private = quaternion;
385 assert(argv != NULL && outQuaternion != NULL);
387 if (outConsumed != NULL) *outConsumed = 0;
390 if (JSVAL_IS_OBJECT(argv[0]))
394 if (outConsumed != NULL) *outConsumed = 1;
399 if (!permitNumberList)
return NO;
405 if (
EXPECT_NOT(!JS_ValueToNumber(context, argv[0], &w) || isnan(w)))
return NO;
406 if (
EXPECT_NOT(!JS_ValueToNumber(context, argv[1], &
x) || isnan(
x)))
return NO;
407 if (
EXPECT_NOT(!JS_ValueToNumber(context, argv[2], &
y) || isnan(
y)))
return NO;
408 if (
EXPECT_NOT(!JS_ValueToNumber(context, argv[3], &z) || isnan(z)))
return NO;
411 *outQuaternion = make_quaternion(w,
x,
y, z);
412 if (outConsumed != NULL) *outConsumed = 4;
421BOOL
QuaternionFromArgumentList(JSContext *context, NSString *scriptClass, NSString *
function, uintN argc, jsval *argv, Quaternion *outQuaternion, uintN *outConsumed)
427 @"Could not construct quaternion from parameters",
428 @"Quaternion, Entity or four numbers");
444 if (!JSID_IS_INT(propID))
return YES;
448 Quaternion quaternion;
453 switch (JSID_TO_INT(propID))
456 fValue = quaternion.w;
460 fValue = quaternion.x;
464 fValue = quaternion.y;
468 fValue = quaternion.z;
476 return JS_NewNumberValue(context, fValue, value);
484 if (!JSID_IS_INT(propID))
return YES;
488 Quaternion quaternion;
492 if (
EXPECT_NOT(!JS_ValueToNumber(context, *value, &dval)))
498 switch (JSID_TO_INT(propID))
529 Quaternion *
private = NULL;
544 Quaternion *
private = NULL;
545 JSObject *
this = NULL;
547 private = malloc(
sizeof *
private);
559 @"Could not construct quaternion from parameters",
560 @"Quaternion, Entity or array of four numbers");
565 *
private = quaternion;
567 if (!JS_SetPrivate(context,
this,
private))
605 NSString *str = [NSString stringWithFormat:@"Quaternion(%g, %g, %g, %g)", thisq.w, thisq.x, thisq.y, thisq.z];
617 Quaternion thisq, thatq, result;
635 Quaternion thisq, thatq;
641 result = quaternion_dot_product(thisq, thatq);
743 quaternion_normalize(&quat);
756 Quaternion quat, result;
760 result = quaternion_conjugate(quat);
828 JSObject *result = NULL;
834 result = JS_NewArrayObject(context, 0, NULL);
840 if (JS_NewNumberValue(context, thisq.w, &nVal)) JS_SetElement(context, result, 0, &nVal);
842 if (JS_NewNumberValue(context, thisq.x, &nVal)) JS_SetElement(context, result, 1, &nVal);
844 if (JS_NewNumberValue(context, thisq.y, &nVal)) JS_SetElement(context, result, 2, &nVal);
846 if (JS_NewNumberValue(context, thisq.z, &nVal)) JS_SetElement(context, result, 3, &nVal);
#define OOJS_PROFILE_EXIT
#define OOJS_NATIVE_ENTER(cx)
#define OOJS_PROFILE_ENTER
OOINLINE JSClass * JSEntityClass(void)
BOOL BOOL JSQuaternionSetQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion quaternion) GCC_ATTR((nonnull(1)))
BOOL QuaternionFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, Quaternion *outQuaternion, uintN *outConsumed) GCC_ATTR((nonnull(1
BOOL BOOL QuaternionFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv, Quaternion *outVector, uintN *outConsumed) GCC_ATTR((nonnull(1
BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion *outQuaternion) GCC_ATTR((nonnull(1
JSObject * JSQuaternionWithQuaternion(JSContext *context, Quaternion quaternion)
static JSBool QuaternionRotate(JSContext *context, uintN argc, jsval *vp)
static JSClass sQuaternionClass
BOOL JSValueToQuaternion(JSContext *context, jsval value, Quaternion *outQuaternion)
void InitOOJSQuaternion(JSContext *context, JSObject *global)
static JSBool QuaternionToArray(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionStaticRandom(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionRotateY(JSContext *context, uintN argc, jsval *vp)
static BOOL GetThisQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion *outQuaternion, NSString *method) NONNULL_FUNC
static JSBool QuaternionToString(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionToSource(JSContext *context, uintN argc, jsval *vp)
static JSObject * sQuaternionPrototype
static JSBool QuaternionVectorRight(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionConstruct(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionRotateX(JSContext *context, uintN argc, jsval *vp)
BOOL QuaternionToJSValue(JSContext *context, Quaternion quaternion, jsval *outValue)
static JSBool QuaternionGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
static JSBool QuaternionMultiply(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionVectorForward(JSContext *context, uintN argc, jsval *vp)
static JSFunctionSpec sQuaternionMethods[]
static JSPropertySpec sQuaternionProperties[]
static BOOL QuaternionFromArgumentListNoErrorInternal(JSContext *context, uintN argc, jsval *argv, Quaternion *outQuaternion, uintN *outConsumed, BOOL permitNumberList)
static JSBool QuaternionRotateZ(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionVectorUp(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
static void QuaternionFinalize(JSContext *context, JSObject *this)
static JSBool QuaternionConjugate(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionNormalize(JSContext *context, uintN argc, jsval *vp)
static JSBool QuaternionDot(JSContext *context, uintN argc, jsval *vp)
static JSFunctionSpec sQuaternionStaticMethods[]
BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion *outQuaternion)
BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed) GCC_ATTR((nonnull(1
BOOL OOJSArgumentListGetNumber(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, double *outNumber, uintN *outConsumed)
#define OOJS_PROP_READWRITE_CB
#define OOJS_RETURN_DOUBLE(value)
#define OOJS_RETURN_OBJECT(o)
void OOJSReportBadPropertySelector(JSContext *context, JSObject *thisObj, jsid propID, JSPropertySpec *propertySpec)
OOINLINE BOOL OOJSIsMemberOfSubclass(JSContext *context, JSObject *object, JSClass *superclass)
#define OOJS_RETURN_QUATERNION(value)
#define OOJS_RETURN_JSOBJECT(o)
void OOJSReportBadPropertyValue(JSContext *context, JSObject *thisObj, jsid propID, JSPropertySpec *propertySpec, jsval value)
void OOJSReportBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription)
#define OOJS_RETURN_VECTOR(value)
Vector vector_up_from_quaternion(Quaternion quat)
void quaternion_rotate_about_x(Quaternion *quat, OOScalar angle)
Vector vector_right_from_quaternion(Quaternion quat)
Vector vector_forward_from_quaternion(Quaternion quat)
void quaternion_rotate_about_z(Quaternion *quat, OOScalar angle)
const Quaternion kIdentityQuaternion
void quaternion_rotate_about_y(Quaternion *quat, OOScalar angle)
const Quaternion kZeroQuaternion
void quaternion_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle)
Quaternion quaternion_multiply(Quaternion q1, Quaternion q2)