69 float inverseTranslation[16];
77 float inverseRotation[16] = {
100 VuoPoint3d inverseScale = (VuoPoint3d){
105 if (isnan(inverseScale.x) || isinf(inverseScale.x))
107 if (isnan(inverseScale.y) || isinf(inverseScale.y))
109 if (isnan(inverseScale.z) || isinf(inverseScale.z))
112 float inverseScaleMatrix[16];
219 matrix[0] = 1. - 2. * (quaternion.y * quaternion.y + quaternion.z * quaternion.z);
220 matrix[1] = 2. * (quaternion.x * quaternion.y + quaternion.w * quaternion.z);
221 matrix[2] = 2. * (quaternion.x * quaternion.z - quaternion.w * quaternion.y);
222 matrix[3] = 2. * (quaternion.x * quaternion.y - quaternion.w * quaternion.z);
223 matrix[4] = 1. - 2. * (quaternion.x * quaternion.x + quaternion.z * quaternion.z);
224 matrix[5] = 2. * (quaternion.y * quaternion.z + quaternion.w * quaternion.x);
225 matrix[6] = 2. * (quaternion.x * quaternion.z + quaternion.w * quaternion.y);
226 matrix[7] = 2. * (quaternion.y * quaternion.z - quaternion.w * quaternion.x);
227 matrix[8] = 1. - 2. * (quaternion.x * quaternion.x + quaternion.y * quaternion.y);
235 matrix[0] = cos(euler.y)*cos(euler.z);
236 matrix[1] = cos(euler.y)*sin(euler.z);
237 matrix[2] = -sin(euler.y);
238 matrix[3] = cos(euler.z)*sin(euler.x)*sin(euler.y) - cos(euler.x)*sin(euler.z);
239 matrix[4] = cos(euler.x)*cos(euler.z) + sin(euler.x)*sin(euler.y)*sin(euler.z);
240 matrix[5] = cos(euler.y)*sin(euler.x);
241 matrix[6] = cos(euler.x)*cos(euler.z)*sin(euler.y) + sin(euler.x)*sin(euler.z);
242 matrix[7] = -cos(euler.z)*sin(euler.x) + cos(euler.x)*sin(euler.y)*sin(euler.z);
243 matrix[8] = cos(euler.x)*cos(euler.y);
385 VuoReal left = rectangle.center.x - rectangle.size.x/2.;
386 VuoReal right = rectangle.center.x + rectangle.size.x/2.;
387 VuoReal bottom = rectangle.center.y - rectangle.size.y/2.;
388 VuoReal top = rectangle.center.y + rectangle.size.y/2.;
395 VuoReal transformedLeft =
MIN(
MIN(
MIN(topLeft.x, topRight.x), bottomLeft.x), bottomRight.x);
396 VuoReal transformedRight =
MAX(
MAX(
MAX(topLeft.x, topRight.x), bottomLeft.x), bottomRight.x);
397 VuoReal transformedBottom =
MIN(
MIN(
MIN(topLeft.y, topRight.y), bottomLeft.y), bottomRight.y);
398 VuoReal transformedTop =
MAX(
MAX(
MAX(topLeft.y, topRight.y), bottomLeft.y), bottomRight.y);
401 (transformedLeft + transformedRight)/2.,
402 (transformedBottom + transformedTop)/2.,
403 transformedRight - transformedLeft,
404 transformedTop - transformedBottom);
406 return transformedRectangle;
414void VuoTransform_getBillboardMatrix(
VuoInteger imageWidth,
VuoInteger imageHeight,
VuoReal imageScaleFactor,
VuoBoolean preservePhysicalSize,
VuoReal translationX,
VuoReal translationY,
VuoInteger viewportWidth,
VuoInteger viewportHeight,
VuoReal backingScaleFactor, VuoPoint2d mesh0,
float *billboardMatrix)
416 VuoReal combinedScaleFactor = 1;
417 if (preservePhysicalSize)
418 combinedScaleFactor = backingScaleFactor / imageScaleFactor;
422 imageWidth *= combinedScaleFactor;
423 imageHeight *= combinedScaleFactor;
429 if (viewportWidth <= 0)
431 billboardMatrix[0] = 0;
432 billboardMatrix[5] = 0;
433 billboardMatrix[12] = translationX;
434 billboardMatrix[13] = translationY;
439 billboardMatrix[0] = 2. * imageWidth/viewportWidth;
440 billboardMatrix[5] = billboardMatrix[0] * imageHeight/imageWidth;
444 billboardMatrix[12] = floor((translationX+1.)/2.*viewportWidth) / ((float)viewportWidth) * 2. - 1.;
445 billboardMatrix[13] = floor((translationY+1.)/2.*viewportWidth) / ((float)viewportWidth) * 2. - 1.;
452 billboardMatrix[12] += (imageWidth % 2 ? (1./viewportWidth) : 0);
455 billboardMatrix[13] -= (imageHeight % 2 ? (1./viewportWidth) : 0);
458 billboardMatrix[13] += (viewportWidth % 2 ? (1./viewportWidth) : 0);
459 billboardMatrix[13] -= (viewportHeight % 2 ? (1./viewportWidth) : 0);
516 json_object *o = NULL;
518 if (json_object_object_get_ex(js,
"target", &o))
521 target.x = json_object_get_double(json_object_array_get_idx(o,0));
522 target.y = json_object_get_double(json_object_array_get_idx(o,1));
523 target.z = json_object_get_double(json_object_array_get_idx(o,2));
526 if (json_object_object_get_ex(js,
"translation", &o))
528 position.x = json_object_get_double(json_object_array_get_idx(o,0));
529 position.y = json_object_get_double(json_object_array_get_idx(o,1));
530 position.z = json_object_get_double(json_object_array_get_idx(o,2));
534 if (json_object_object_get_ex(js,
"upDirection", &o))
536 upDirection.x = json_object_get_double(json_object_array_get_idx(o,0));
537 upDirection.y = json_object_get_double(json_object_array_get_idx(o,1));
538 upDirection.z = json_object_get_double(json_object_array_get_idx(o,2));
544 if (json_object_object_get_ex(js,
"quaternionRotation", &o))
546 t.type = VuoTransformTypeQuaternion;
548 q.x = json_object_get_double(json_object_array_get_idx(o,0));
549 q.y = json_object_get_double(json_object_array_get_idx(o,1));
550 q.z = json_object_get_double(json_object_array_get_idx(o,2));
551 q.w = json_object_get_double(json_object_array_get_idx(o,3));
554 else if (json_object_object_get_ex(js,
"eulerRotation", &o))
556 t.type = VuoTransformTypeEuler;
558 e.x = json_object_get_double(json_object_array_get_idx(o,0));
559 e.y = json_object_get_double(json_object_array_get_idx(o,1));
560 e.z = json_object_get_double(json_object_array_get_idx(o,2));
564 if (json_object_object_get_ex(js,
"translation", &o))
566 t.translation.x = json_object_get_double(json_object_array_get_idx(o,0));
567 t.translation.y = json_object_get_double(json_object_array_get_idx(o,1));
568 t.translation.z = json_object_get_double(json_object_array_get_idx(o,2));
571 if (json_object_object_get_ex(js,
"scale", &o))
573 t.scale.x = json_object_get_double(json_object_array_get_idx(o,0));
574 t.scale.y = json_object_get_double(json_object_array_get_idx(o,1));
575 t.scale.z = json_object_get_double(json_object_array_get_idx(o,2));
599 return json_object_new_string(
"identity");
601 json_object *js = json_object_new_object();
604 json_object * o = json_object_new_array();
605 json_object_array_add(o,json_object_new_double(
cook(value.translation.x)));
606 json_object_array_add(o,json_object_new_double(
cook(value.translation.y)));
607 json_object_array_add(o,json_object_new_double(
cook(value.translation.z)));
608 json_object_object_add(js,
"translation", o);
613 if (value.type == VuoTransformTypeQuaternion)
615 json_object * o = json_object_new_array();
616 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.quaternion.x)));
617 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.quaternion.y)));
618 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.quaternion.z)));
619 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.quaternion.w)));
620 json_object_object_add(js,
"quaternionRotation", o);
622 else if (value.type == VuoTransformTypeEuler)
624 json_object * o = json_object_new_array();
625 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.euler.x)));
626 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.euler.y)));
627 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.euler.z)));
628 json_object_object_add(js,
"eulerRotation", o);
632 json_object * o = json_object_new_array();
633 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.target.x)));
634 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.target.y)));
635 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.target.z)));
636 json_object_object_add(js,
"target", o);
638 o = json_object_new_array();
639 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.upDirection.x)));
640 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.upDirection.y)));
641 json_object_array_add(o,json_object_new_double(
cook(value.rotationSource.upDirection.z)));
642 json_object_object_add(js,
"upDirection", o);
645 if (value.type != VuoTransformTypeTargeted)
647 json_object * o = json_object_new_array();
648 json_object_array_add(o,json_object_new_double(
cook(value.scale.x)));
649 json_object_array_add(o,json_object_new_double(
cook(value.scale.y)));
650 json_object_array_add(o,json_object_new_double(
cook(value.scale.z)));
651 json_object_object_add(js,
"scale", o);
665 return strdup(
"Identity transform (no change)");
667 if (value.type == VuoTransformTypeTargeted)
668 return VuoText_format(
"<div>Position (%g, %g, %g)</div>\n<div>Target (%g, %g, %g)</div>\n<div>Up (%g, %g, %g)</div>",
669 value.translation.x, value.translation.y, value.translation.z, value.rotationSource.target.x, value.rotationSource.target.y, value.rotationSource.target.z, value.rotationSource.upDirection.x, value.rotationSource.upDirection.y, value.rotationSource.upDirection.z);
672 if (value.type == VuoTransformTypeQuaternion)
674 value.rotationSource.quaternion.x, value.rotationSource.quaternion.y, value.rotationSource.quaternion.z, value.rotationSource.quaternion.w);
682 char *valueAsString =
VuoText_format(
"<div>Translation (%g, %g, %g)</div>\n<div>Rotation %s</div>\n<div>Scale (%g, %g, %g)</div>",
683 value.translation.x, value.translation.y, value.translation.z, rotation, value.scale.x, value.scale.y, value.scale.z);
685 return valueAsString;