Vuo  2.1.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 
63 VuoLayer VuoLayer_make(VuoText name, VuoImage image, VuoPoint2d center, VuoReal rotation, VuoReal size, VuoOrientation fixed, VuoReal alpha)
64 {
65  VuoPoint3d center3d = VuoPoint3d_make(center.x, center.y, 0);
66  VuoPoint3d rotation3d = VuoPoint3d_make(0, 0, rotation);
67  VuoSceneObject so = VuoSceneObject_makeImage(image, center3d, rotation3d, size, fixed, alpha);
68  VuoSceneObject_setName(so, name);
69  return (VuoLayer)so;
70 }
71 
81 {
82  VuoPoint3d center3d = VuoPoint3d_make(transform.translation.x, transform.translation.y, 0);
83  // VuoSceneObject_makeImage wants rotation in degrees
84  VuoPoint3d rotation3d = VuoPoint3d_make(0, 0, transform.rotation * 57.295779513f);
85  VuoSceneObject so = VuoSceneObject_makeImage(image, center3d, rotation3d, 2, VuoOrientation_Horizontal, alpha);
86  VuoSceneObject_setScale(so, (VuoPoint3d){transform.scale.x, transform.scale.y, 1});
87  VuoSceneObject_setName(so, name);
88  return (VuoLayer)so;
89 }
90 
102 VuoLayer VuoLayer_makeRealSize(VuoText name, VuoImage image, VuoPoint2d center, VuoReal alpha, VuoBoolean preservePhysicalSize)
103 {
104  VuoLayer l = VuoLayer_make(name, image, center, 0, 0, VuoOrientation_Horizontal, alpha);
106  VuoSceneObject_setPreservePhysicalSize((VuoSceneObject)l, preservePhysicalSize);
107  return l;
108 }
109 
126 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)
127 {
128  if (!image)
129  return NULL;
130 
131  // Create a pair of layers, one for the main layer and one for the shadow, and put them in a group.
132  // Apply the transformation to the individual layers, rather than to the group, so that
133  // VuoRenderedLayers_getTransformedLayer() can work with the individual layers.
134 
135  float rotationInRadians = rotation * M_PI/180.;
136  VuoTransform groupTransform = VuoTransform_makeFrom2d( VuoTransform2d_make(center, rotationInRadians, VuoPoint2d_make(width,width)) );
137  float matrix[16];
138  VuoTransform_getMatrix(groupTransform, matrix);
139 
140  VuoPoint3d center3d = VuoPoint3d_make(0,0,0);
141  VuoPoint3d layerCenter3d = VuoTransform_transformPoint(matrix, center3d);
142  VuoPoint2d layerCenter = VuoPoint2d_make(layerCenter3d.x, layerCenter3d.y);
143  VuoLayer layer = VuoLayer_make(name, image, layerCenter, rotation, width, VuoOrientation_Horizontal, alpha);
144  VuoSceneObject_setRealSize((VuoSceneObject)layer, isRealSize);
145  VuoSceneObject_setPreservePhysicalSize((VuoSceneObject)layer, preservePhysicalSize);
146 
148  VuoRetain(colors);
149  VuoListAppendValue_VuoColor(colors, shadowColor);
150  VuoImage recoloredImage = VuoImage_mapColors(image, colors, 1);
151  VuoRetain(recoloredImage);
152  VuoRelease(colors);
153 
155  VuoRetain(ib);
156  VuoImage blurredImage = VuoImageBlur_blur(ib, recoloredImage, NULL, VuoBlurShape_Gaussian, shadowBlur, 1, TRUE);
157  VuoRelease(ib);
158  float shadowAngleInRadians = shadowAngle * M_PI/180.;
159  VuoPoint3d shadowOffset3d = VuoPoint3d_make(shadowDistance * cos(shadowAngleInRadians),
160  shadowDistance * sin(shadowAngleInRadians),
161  0);
162  VuoPoint3d shadowCenter3d = VuoTransform_transformPoint(matrix, shadowOffset3d);
163  VuoPoint2d shadowCenter = VuoPoint2d_make(shadowCenter3d.x, shadowCenter3d.y);
164  VuoReal shadowWidth = width * blurredImage->pixelsWide/image->pixelsWide;
165  VuoLayer shadow = VuoLayer_make(NULL, blurredImage, shadowCenter, rotation, shadowWidth, VuoOrientation_Horizontal, alpha);
166  VuoSceneObject_setRealSize((VuoSceneObject)shadow, isRealSize);
167  VuoSceneObject_setPreservePhysicalSize((VuoSceneObject)shadow, preservePhysicalSize);
168 
170  VuoRetain(layers);
171  VuoListAppendValue_VuoLayer(layers, shadow);
172  VuoListAppendValue_VuoLayer(layers, layer);
173 
174  VuoRelease(recoloredImage);
175 
177  VuoRelease(layers);
178 
179  return group;
180 }
181 
196 VuoLayer VuoLayer_makeWithShadow(VuoText name, VuoImage image, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal alpha, VuoColor shadowColor, VuoReal shadowBlur, VuoReal shadowAngle, VuoReal shadowDistance)
197 {
198  return VuoLayer_makeWithShadowInternal(name,image,center,rotation,width,alpha,false,shadowColor,shadowBlur,shadowAngle,shadowDistance,false);
199 }
200 
216 VuoLayer VuoLayer_makeRealSizeWithShadow(VuoText name, VuoImage image, VuoPoint2d center, VuoReal alpha, VuoBoolean preservePhysicalSize, VuoColor shadowColor, VuoReal shadowBlur, VuoReal shadowAngle, VuoReal shadowDistance)
217 {
218  return VuoLayer_makeWithShadowInternal(name,image,center,0,1,alpha,preservePhysicalSize,shadowColor,shadowBlur,shadowAngle,shadowDistance,true);
219 }
220 
231 VuoLayer VuoLayer_makeColor(VuoText name, VuoColor color, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height)
232 {
235  VuoPoint3d_make(center.x, center.y, 0),
236  VuoPoint3d_make(0, 0, rotation),
237  width,
238  height
239  );
240  VuoSceneObject_setName(so, name);
241  return (VuoLayer)so;
242 }
243 
255 VuoLayer VuoLayer_makeOval(VuoText name, VuoColor color, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal sharpness)
256 {
257  // Since VuoShader_makeUnlitCircleShader() produces a shader that fills half the size (to leave enough room for sharpness=0),
258  // make the layer twice the specified size.
260  VuoShader_makeUnlitCircleShader(color, sharpness),
261  VuoPoint3d_make(center.x, center.y, 0),
262  VuoPoint3d_make(0, 0, rotation),
263  width*2,
264  height*2
265  );
266  VuoSceneObject_setName(so, name);
267  return (VuoLayer)so;
268 }
269 
283 VuoLayer VuoLayer_makeCheckmark(VuoText name, VuoColor fillColor, VuoColor outlineColor, VuoReal outlineThickness, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height)
284 {
286  VuoShader_makeUnlitCheckmarkShader(fillColor, outlineColor, outlineThickness),
287  VuoPoint3d_make(center.x, center.y, 0),
288  VuoPoint3d_make(0, 0, rotation),
289  width,
290  height );
291  VuoSceneObject_setName(so, name);
292  return (VuoLayer)so;
293 }
294 
307 VuoLayer VuoLayer_makeRoundedRectangle(VuoText name, VuoColor color, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal sharpness, VuoReal roundness)
308 {
310  VuoShader_makeUnlitRoundedRectangleShader(color, sharpness, roundness, width/height),
311  VuoPoint3d_make(center.x, center.y, 0),
312  VuoPoint3d_make(0, 0, rotation),
313  width * 2,
314  height * 2
315  );
316  VuoSceneObject_setName(so, name);
317  return (VuoLayer)so;
318 }
319 
333 VuoLayer VuoLayer_makeLinearGradient(VuoText name, VuoList_VuoColor colors, VuoPoint2d start, VuoPoint2d end, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal noiseAmount)
334 {
336  VuoShader_setLinearGradientShaderValues(shader, colors, start, end, 1, noiseAmount);
338  shader,
339  VuoPoint3d_make(center.x, center.y, 0),
340  VuoPoint3d_make(0, 0, rotation),
341  width,
342  height
343  );
344  VuoSceneObject_setName(so, name);
345  return (VuoLayer)so;
346 }
347 
361 VuoLayer VuoLayer_makeRadialGradient(VuoText name, VuoList_VuoColor colors, VuoPoint2d gradientCenter, VuoReal radius, VuoPoint2d center, VuoReal rotation, VuoReal width, VuoReal height, VuoReal noiseAmount)
362 {
364  VuoShader_setRadialGradientShaderValues(shader, colors, gradientCenter, radius, width, height, noiseAmount);
366  shader,
367  VuoPoint3d_make(center.x, center.y, 0),
368  VuoPoint3d_make(0, 0, rotation),
369  width,
370  height
371  );
372  VuoSceneObject_setName(so, name);
373  return (VuoLayer)so;
374 }
375 
380 {
382 
383  unsigned long childLayerCount = VuoListGetCount_VuoLayer(childLayers);
384  for (unsigned long i = 1; i <= childLayerCount; ++i)
386 
387  return (VuoLayer)so;
388 }
389 
395 {
397  VuoLocal(group);
398  VuoListAppendValue_VuoLayer(group, layer1);
399  VuoListAppendValue_VuoLayer(group, layer2);
400  return VuoLayer_makeGroup(group, transform);
401 }
402 
408 {
410  VuoLocal(group);
411  VuoListAppendValue_VuoLayer(group, layer1);
412  VuoListAppendValue_VuoLayer(group, layer2);
413  VuoListAppendValue_VuoLayer(group, layer3);
414  return VuoLayer_makeGroup(group, transform);
415 }
416 
423 uint64_t VuoLayer_getId(const VuoLayer layer)
424 {
425  return VuoSceneObject_getId((VuoSceneObject)layer);
426 }
427 
434 void VuoLayer_setId(VuoLayer layer, uint64_t id)
435 {
437 }
438 
443 {
444  unsigned long childLayerCount = VuoListGetCount_VuoSceneObject(VuoSceneObject_getChildObjects((VuoSceneObject)layer));
445  if (childLayerCount == 0)
446  return NULL;
447 
448  VuoList_VuoLayer childLayers = VuoListCreateWithCount_VuoLayer(childLayerCount, NULL);
449  VuoLayer *childLayersData = VuoListGetData_VuoLayer(childLayers);
451  for (unsigned int i = 0; i < childLayerCount; ++i)
452  {
453  childLayersData[i] = (VuoLayer)objects[i];
454  VuoLayer_retain(childLayersData[i]);
455  }
456  return childLayers;
457 }
458 
462 static VuoRectangle VuoLayer_getBoundingRectangleWithSceneObject(VuoSceneObject so, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
463 {
464  VuoRectangle b = VuoRectangle_make(NAN,NAN,0,0);
465 
466  float matrix[16];
467 
468  if (VuoSceneObject_getType(so) == VuoSceneObjectSubType_Text)
469  {
471  viewportWidth = VuoGraphicsWindowDefaultWidth * backingScaleFactor;
472 
473  if (viewportWidth > 0)
474  {
476  b.size = VuoPoint2d_multiply(b.size, 2./viewportWidth);
477 
478  if (VuoSceneObject_getMesh(so))
479  {
480  VuoPoint2d anchorOffset = VuoAnchor_getOffset(VuoSceneText_getAnchor(so));
481  b.center.x += anchorOffset.x * b.size.x;
482  b.center.y += anchorOffset.y * b.size.y;
483  }
484 
486  b = VuoTransform_transformRectangle(matrix, b);
487  }
488  else
489  {
490  b = VuoImage_getTextRectangle(VuoSceneObject_getText(so), VuoSceneObject_getTextFont(so), backingScaleFactor, 1, 0, INFINITY, false);
491  b.center = VuoSceneObject_getTranslation(so).xy;
493  }
494  }
495 
496  VuoShader shader = VuoSceneObject_getShader(so);
497  if (shader)
498  {
499  VuoImage image = VuoShader_getUniform_VuoImage(shader, "texture");
500  if (image && VuoSceneObject_isRealSize(so))
501  {
502  VuoMesh mesh = VuoSceneObject_getMesh(so);
503  float *positions;
504  VuoMesh_getCPUBuffers(mesh, NULL, &positions, NULL, NULL, NULL, NULL, NULL);
505  VuoPoint2d mesh0 = (VuoPoint2d){ positions[0], positions[1] };
506  VuoTransform_getBillboardMatrix(image->pixelsWide, image->pixelsHigh, image->scaleFactor, VuoSceneObject_shouldPreservePhysicalSize(so), VuoSceneObject_getTranslation(so).x, VuoSceneObject_getTranslation(so).y, viewportWidth, viewportHeight, backingScaleFactor, mesh0, matrix);
507  }
508  else
510 
511  b = VuoTransform_transformRectangle(matrix, VuoRectangle_make(0, 0, shader->objectScale, shader->objectScale));
512  }
513  else
515 
517  if (childObjects)
518  {
519  unsigned long childObjectCount = VuoListGetCount_VuoSceneObject(childObjects);
520  for (unsigned long i = 1; i <= childObjectCount; ++i)
521  {
522  VuoSceneObject child = VuoListGetValue_VuoSceneObject(childObjects, i);
523  VuoRectangle childBoundingBox = VuoLayer_getBoundingRectangleWithSceneObject(child, viewportWidth, viewportHeight, backingScaleFactor);
524  childBoundingBox = VuoTransform_transformRectangle(matrix, childBoundingBox);
525  if (!isnan(childBoundingBox.center.x))
526  {
527  if (!isnan(b.center.x))
528  b = VuoRectangle_union(b, childBoundingBox);
529  else
530  b = childBoundingBox;
531  }
532  }
533  }
534 
535  return b;
536 }
537 
544 VuoLayer VuoLayer_setAnchor(VuoLayer child, VuoAnchor anchor, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
545 {
547  return child;
548 
551 
552  VuoRectangle rect = VuoLayer_getBoundingRectangle(child, viewportWidth, viewportHeight, backingScaleFactor);
553 
554  VuoPoint3d childTranslation = childTransform.translation;
555  VuoPoint2d boundsCenter = rect.center;
556  VuoPoint3d parentTranslation = VuoPoint3d_make(childTranslation.x - boundsCenter.x, childTranslation.y - boundsCenter.y, 0);
557 
558  if (VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Left)
559  boundsCenter.x += rect.size.x * .5f;
560  else if (VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Right)
561  boundsCenter.x -= rect.size.x * .5f;
562 
563  if (VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Top)
564  boundsCenter.y -= rect.size.y * .5f;
565  else if (VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Bottom)
566  boundsCenter.y += rect.size.y * .5f;
567 
568  VuoSceneObject_translate((VuoSceneObject)child, (VuoPoint3d){boundsCenter.x, boundsCenter.y, 0});
569 
570  VuoTransform parentTransform = childTransform;
571  parentTransform.translation = parentTranslation;
572 
574 
577 
579 
580  return parent;
581 }
582 
586 VuoRectangle VuoLayer_getBoundingRectangle(VuoLayer layer, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
587 {
588  return VuoLayer_getBoundingRectangleWithSceneObject((VuoSceneObject)layer, viewportWidth, viewportHeight, backingScaleFactor);
589 }
590 
595 {
597 }
598 
604 {
606 }
607 
613 {
614  return VuoSceneObject_getJson((VuoSceneObject)value);
615 }
616 
621 char * VuoLayer_getSummary(const VuoLayer value)
622 {
624 }