Vuo  2.0.0
VuoLayer.c
Go to the documentation of this file.
1 
10 #include "type.h"
11 #include "VuoLayer.h"
12 #include "VuoAnchor.h"
13 #include "VuoImageBlur.h"
14 #include "VuoImageText.h"
15 #include "VuoSceneText.h"
16 
18 #ifdef VUO_COMPILER
20  "title" : "Layer",
21  "description" : "A 2D Layer: visible (image), or virtual (group).",
22  "keywords" : [ ],
23  "version" : "1.0.0",
24  "dependencies" : [
25  "VuoAnchor",
26  "VuoColor",
27  "VuoImageBlur",
28  "VuoImageText",
29  "VuoPoint2d",
30  "VuoRectangle",
31  "VuoSceneObject",
32  "VuoSceneText",
33  "VuoTransform2d",
34  "VuoWindowReference",
35  "VuoList_VuoColor",
36  "VuoList_VuoLayer",
37  "VuoList_VuoSceneObject"
38  ]
39  });
40 #endif
41 
43 
48 {
50 }
51 
62 VuoLayer VuoLayer_make(VuoText name, VuoImage image, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal alpha)
63 {
64  VuoPoint3d center3d = VuoPoint3d_make(center.x, center.y, 0);
65  VuoPoint3d rotation3d = VuoPoint3d_make(0, 0, rotation);
66  VuoSceneObject so = VuoSceneObject_makeImage(image, center3d, rotation3d, width, alpha);
67  VuoSceneObject_setName(so, name);
68  return (VuoLayer)so;
69 }
70 
80 {
81  VuoPoint3d center3d = VuoPoint3d_make(transform.translation.x, transform.translation.y, 0);
82  // VuoSceneObject_makeImage wants rotation in degrees
83  VuoPoint3d rotation3d = VuoPoint3d_make(0, 0, transform.rotation * 57.295779513f);
84  VuoSceneObject so = VuoSceneObject_makeImage(image, center3d, rotation3d, 2, alpha);
85  VuoSceneObject_setScale(so, (VuoPoint3d){transform.scale.x, transform.scale.y, 1});
86  VuoSceneObject_setName(so, name);
87  return (VuoLayer)so;
88 }
89 
101 VuoLayer VuoLayer_makeRealSize(VuoText name, VuoImage image, VuoPoint2d center, VuoReal alpha, VuoBoolean preservePhysicalSize)
102 {
103  VuoLayer l = VuoLayer_make(name,image,center,0,0,alpha);
105  VuoSceneObject_setPreservePhysicalSize((VuoSceneObject)l, preservePhysicalSize);
106  return l;
107 }
108 
125 static VuoLayer VuoLayer_makeWithShadowInternal(VuoText name, VuoImage image, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal alpha, VuoBoolean preservePhysicalSize, VuoColor shadowColor, VuoReal shadowBlur, VuoReal shadowAngle, VuoReal shadowDistance, VuoBoolean isRealSize)
126 {
127  if (!image)
128  return NULL;
129 
130  // Create a pair of layers, one for the main layer and one for the shadow, and put them in a group.
131  // Apply the transformation to the individual layers, rather than to the group, so that
132  // VuoRenderedLayers_getTransformedLayer() can work with the individual layers.
133 
134  float rotationInRadians = rotation * M_PI/180.;
135  VuoTransform groupTransform = VuoTransform_makeFrom2d( VuoTransform2d_make(center, rotationInRadians, VuoPoint2d_make(width,width)) );
136  float matrix[16];
137  VuoTransform_getMatrix(groupTransform, matrix);
138 
139  VuoPoint3d center3d = VuoPoint3d_make(0,0,0);
140  VuoPoint3d layerCenter3d = VuoTransform_transformPoint(matrix, center3d);
141  VuoPoint2d layerCenter = VuoPoint2d_make(layerCenter3d.x, layerCenter3d.y);
142  VuoLayer layer = VuoLayer_make(name, image, layerCenter, rotation, width, alpha);
143  VuoSceneObject_setRealSize((VuoSceneObject)layer, isRealSize);
144  VuoSceneObject_setPreservePhysicalSize((VuoSceneObject)layer, preservePhysicalSize);
145 
147  VuoRetain(colors);
148  VuoListAppendValue_VuoColor(colors, shadowColor);
149  VuoImage recoloredImage = VuoImage_mapColors(image, colors, 1);
150  VuoRetain(recoloredImage);
151  VuoRelease(colors);
152 
154  VuoRetain(ib);
155  VuoImage blurredImage = VuoImageBlur_blur(ib, recoloredImage, NULL, VuoBlurShape_Gaussian, shadowBlur, 1, TRUE);
156  VuoRelease(ib);
157  float shadowAngleInRadians = shadowAngle * M_PI/180.;
158  VuoPoint3d shadowOffset3d = VuoPoint3d_make(shadowDistance * cos(shadowAngleInRadians),
159  shadowDistance * sin(shadowAngleInRadians),
160  0);
161  VuoPoint3d shadowCenter3d = VuoTransform_transformPoint(matrix, shadowOffset3d);
162  VuoPoint2d shadowCenter = VuoPoint2d_make(shadowCenter3d.x, shadowCenter3d.y);
163  VuoReal shadowWidth = width * blurredImage->pixelsWide/image->pixelsWide;
164  VuoLayer shadow = VuoLayer_make(NULL, blurredImage, shadowCenter, rotation, shadowWidth, alpha);
165  VuoSceneObject_setRealSize((VuoSceneObject)shadow, isRealSize);
166  VuoSceneObject_setPreservePhysicalSize((VuoSceneObject)shadow, preservePhysicalSize);
167 
169  VuoRetain(layers);
170  VuoListAppendValue_VuoLayer(layers, shadow);
171  VuoListAppendValue_VuoLayer(layers, layer);
172 
173  VuoRelease(recoloredImage);
174 
176  VuoRelease(layers);
177 
178  return group;
179 }
180 
195 VuoLayer VuoLayer_makeWithShadow(VuoText name, VuoImage image, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal alpha, VuoColor shadowColor, VuoReal shadowBlur, VuoReal shadowAngle, VuoReal shadowDistance)
196 {
197  return VuoLayer_makeWithShadowInternal(name,image,center,rotation,width,alpha,false,shadowColor,shadowBlur,shadowAngle,shadowDistance,false);
198 }
199 
215 VuoLayer VuoLayer_makeRealSizeWithShadow(VuoText name, VuoImage image, VuoPoint2d center, VuoReal alpha, VuoBoolean preservePhysicalSize, VuoColor shadowColor, VuoReal shadowBlur, VuoReal shadowAngle, VuoReal shadowDistance)
216 {
217  return VuoLayer_makeWithShadowInternal(name,image,center,0,1,alpha,preservePhysicalSize,shadowColor,shadowBlur,shadowAngle,shadowDistance,true);
218 }
219 
230 VuoLayer VuoLayer_makeColor(VuoText name, VuoColor color, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height)
231 {
234  VuoPoint3d_make(center.x, center.y, 0),
235  VuoPoint3d_make(0, 0, rotation),
236  width,
237  height
238  );
239  VuoSceneObject_setName(so, name);
240  return (VuoLayer)so;
241 }
242 
254 VuoLayer VuoLayer_makeOval(VuoText name, VuoColor color, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal sharpness)
255 {
256  // Since VuoShader_makeUnlitCircleShader() produces a shader that fills half the size (to leave enough room for sharpness=0),
257  // make the layer twice the specified size.
259  VuoShader_makeUnlitCircleShader(color, sharpness),
260  VuoPoint3d_make(center.x, center.y, 0),
261  VuoPoint3d_make(0, 0, rotation),
262  width*2,
263  height*2
264  );
265  VuoSceneObject_setName(so, name);
266  return (VuoLayer)so;
267 }
268 
282 VuoLayer VuoLayer_makeCheckmark(VuoText name, VuoColor fillColor, VuoColor outlineColor, VuoReal outlineThickness, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height)
283 {
285  VuoShader_makeUnlitCheckmarkShader(fillColor, outlineColor, outlineThickness),
286  VuoPoint3d_make(center.x, center.y, 0),
287  VuoPoint3d_make(0, 0, rotation),
288  width,
289  height );
290  VuoSceneObject_setName(so, name);
291  return (VuoLayer)so;
292 }
293 
306 VuoLayer VuoLayer_makeRoundedRectangle(VuoText name, VuoColor color, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal sharpness, VuoReal roundness)
307 {
309  VuoShader_makeUnlitRoundedRectangleShader(color, sharpness, roundness, width/height),
310  VuoPoint3d_make(center.x, center.y, 0),
311  VuoPoint3d_make(0, 0, rotation),
312  width * 2,
313  height * 2
314  );
315  VuoSceneObject_setName(so, name);
316  return (VuoLayer)so;
317 }
318 
332 VuoLayer VuoLayer_makeLinearGradient(VuoText name, VuoList_VuoColor colors, VuoPoint2d start, VuoPoint2d end, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal noiseAmount)
333 {
335  VuoShader_setLinearGradientShaderValues(shader, colors, start, end, 1, noiseAmount);
337  shader,
338  VuoPoint3d_make(center.x, center.y, 0),
339  VuoPoint3d_make(0, 0, rotation),
340  width,
341  height
342  );
343  VuoSceneObject_setName(so, name);
344  return (VuoLayer)so;
345 }
346 
360 VuoLayer VuoLayer_makeRadialGradient(VuoText name, VuoList_VuoColor colors, VuoPoint2d gradientCenter, VuoReal radius, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal noiseAmount)
361 {
363  VuoShader_setRadialGradientShaderValues(shader, colors, gradientCenter, radius, width, height, noiseAmount);
365  shader,
366  VuoPoint3d_make(center.x, center.y, 0),
367  VuoPoint3d_make(0, 0, rotation),
368  width,
369  height
370  );
371  VuoSceneObject_setName(so, name);
372  return (VuoLayer)so;
373 }
374 
379 {
381 
382  unsigned long childLayerCount = VuoListGetCount_VuoLayer(childLayers);
383  for (unsigned long i = 1; i <= childLayerCount; ++i)
385 
386  return (VuoLayer)so;
387 }
388 
394 {
396  VuoLocal(group);
397  VuoListAppendValue_VuoLayer(group, layer1);
398  VuoListAppendValue_VuoLayer(group, layer2);
399  return VuoLayer_makeGroup(group, transform);
400 }
401 
407 {
409  VuoLocal(group);
410  VuoListAppendValue_VuoLayer(group, layer1);
411  VuoListAppendValue_VuoLayer(group, layer2);
412  VuoListAppendValue_VuoLayer(group, layer3);
413  return VuoLayer_makeGroup(group, transform);
414 }
415 
422 uint64_t VuoLayer_getId(const VuoLayer layer)
423 {
424  return VuoSceneObject_getId((VuoSceneObject)layer);
425 }
426 
433 void VuoLayer_setId(VuoLayer layer, uint64_t id)
434 {
436 }
437 
442 {
443  unsigned long childLayerCount = VuoListGetCount_VuoSceneObject(VuoSceneObject_getChildObjects((VuoSceneObject)layer));
444  if (childLayerCount == 0)
445  return NULL;
446 
447  VuoList_VuoLayer childLayers = VuoListCreateWithCount_VuoLayer(childLayerCount, NULL);
448  VuoLayer *childLayersData = VuoListGetData_VuoLayer(childLayers);
450  for (unsigned int i = 0; i < childLayerCount; ++i)
451  {
452  childLayersData[i] = (VuoLayer)objects[i];
453  VuoLayer_retain(childLayersData[i]);
454  }
455  return childLayers;
456 }
457 
461 static VuoRectangle VuoLayer_getBoundingRectangleWithSceneObject(VuoSceneObject so, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
462 {
463  VuoRectangle b = VuoRectangle_make(NAN,NAN,0,0);
464 
465  float matrix[16];
466 
467  if (VuoSceneObject_getType(so) == VuoSceneObjectSubType_Text)
468  {
470  viewportWidth = VuoGraphicsWindowDefaultWidth * backingScaleFactor;
471 
472  if (viewportWidth > 0)
473  {
475  b.size = VuoPoint2d_multiply(b.size, 2./viewportWidth);
476 
477  if (VuoSceneObject_getMesh(so))
478  {
479  VuoPoint2d anchorOffset = VuoAnchor_getOffset(VuoSceneText_getAnchor(so));
480  b.center.x += anchorOffset.x * b.size.x;
481  b.center.y += anchorOffset.y * b.size.y;
482  }
483 
485  b = VuoTransform_transformRectangle(matrix, b);
486  }
487  else
488  {
489  b = VuoImage_getTextRectangle(VuoSceneObject_getText(so), VuoSceneObject_getTextFont(so), backingScaleFactor, 1, 0, INFINITY, false);
490  b.center = VuoSceneObject_getTranslation(so).xy;
492  }
493  }
494 
495  VuoShader shader = VuoSceneObject_getShader(so);
496  if (shader)
497  {
498  VuoImage image = VuoShader_getUniform_VuoImage(shader, "texture");
499  if (image && VuoSceneObject_isRealSize(so))
500  {
501  VuoMesh mesh = VuoSceneObject_getMesh(so);
502  float *positions;
503  VuoMesh_getCPUBuffers(mesh, NULL, &positions, NULL, NULL, NULL, NULL, NULL);
504  VuoPoint2d mesh0 = (VuoPoint2d){ positions[0], positions[1] };
505  VuoTransform_getBillboardMatrix(image->pixelsWide, image->pixelsHigh, image->scaleFactor, VuoSceneObject_shouldPreservePhysicalSize(so), VuoSceneObject_getTranslation(so).x, VuoSceneObject_getTranslation(so).y, viewportWidth, viewportHeight, backingScaleFactor, mesh0, matrix);
506  }
507  else
509 
510  b = VuoTransform_transformRectangle(matrix, VuoRectangle_make(0, 0, shader->objectScale, shader->objectScale));
511  }
512  else
514 
516  if (childObjects)
517  {
518  unsigned long childObjectCount = VuoListGetCount_VuoSceneObject(childObjects);
519  for (unsigned long i = 1; i <= childObjectCount; ++i)
520  {
521  VuoSceneObject child = VuoListGetValue_VuoSceneObject(childObjects, i);
522  VuoRectangle childBoundingBox = VuoLayer_getBoundingRectangleWithSceneObject(child, viewportWidth, viewportHeight, backingScaleFactor);
523  childBoundingBox = VuoTransform_transformRectangle(matrix, childBoundingBox);
524  if (!isnan(childBoundingBox.center.x))
525  {
526  if (!isnan(b.center.x))
527  b = VuoRectangle_union(b, childBoundingBox);
528  else
529  b = childBoundingBox;
530  }
531  }
532  }
533 
534  return b;
535 }
536 
543 VuoLayer VuoLayer_setAnchor(VuoLayer child, VuoAnchor anchor, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
544 {
546  return child;
547 
550 
551  VuoRectangle rect = VuoLayer_getBoundingRectangle(child, viewportWidth, viewportHeight, backingScaleFactor);
552 
553  VuoPoint3d childTranslation = childTransform.translation;
554  VuoPoint2d boundsCenter = rect.center;
555  VuoPoint3d parentTranslation = VuoPoint3d_make(childTranslation.x - boundsCenter.x, childTranslation.y - boundsCenter.y, 0);
556 
557  if (VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Left)
558  boundsCenter.x += rect.size.x * .5f;
559  else if (VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Right)
560  boundsCenter.x -= rect.size.x * .5f;
561 
562  if (VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Top)
563  boundsCenter.y -= rect.size.y * .5f;
564  else if (VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Bottom)
565  boundsCenter.y += rect.size.y * .5f;
566 
567  VuoSceneObject_translate((VuoSceneObject)child, (VuoPoint3d){boundsCenter.x, boundsCenter.y, 0});
568 
569  VuoTransform parentTransform = childTransform;
570  parentTransform.translation = parentTranslation;
571 
573 
576 
578 
579  return parent;
580 }
581 
585 VuoRectangle VuoLayer_getBoundingRectangle(VuoLayer layer, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
586 {
587  return VuoLayer_getBoundingRectangleWithSceneObject((VuoSceneObject)layer, viewportWidth, viewportHeight, backingScaleFactor);
588 }
589 
594 {
596 }
597 
603 {
605 }
606 
612 {
613  return VuoSceneObject_getJson((VuoSceneObject)value);
614 }
615 
620 char * VuoLayer_getSummary(const VuoLayer value)
621 {
623 }