Vuo  2.4.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
42
43
48{
50}
51
63VuoLayer 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
102VuoLayer 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);
107 return l;
108}
109
126static 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
196VuoLayer 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
216VuoLayer 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
231VuoLayer 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
255VuoLayer 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
283VuoLayer 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
307VuoLayer 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
333VuoLayer 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
361VuoLayer 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
423uint64_t VuoLayer_getId(const VuoLayer layer)
424{
426}
427
434void VuoLayer_setId(VuoLayer layer, uint64_t id)
435{
437}
438
443{
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
462static 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
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
497 if (shader)
498 {
499 VuoImage image = VuoShader_getUniform_VuoImage(shader, "texture");
500 if (image && VuoSceneObject_isRealSize(so))
501 {
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
544VuoLayer VuoLayer_setAnchor(VuoLayer child, VuoAnchor anchor, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
545{
546 if (!child)
547 return NULL;
548
550 return child;
551
554
555 VuoRectangle rect = VuoLayer_getBoundingRectangle(child, viewportWidth, viewportHeight, backingScaleFactor);
556
557 VuoPoint3d childTranslation = childTransform.translation;
558 VuoPoint2d boundsCenter = rect.center;
559 VuoPoint3d parentTranslation = VuoPoint3d_make(childTranslation.x - boundsCenter.x, childTranslation.y - boundsCenter.y, 0);
560
561 if (VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Left)
562 boundsCenter.x += rect.size.x * .5f;
563 else if (VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Right)
564 boundsCenter.x -= rect.size.x * .5f;
565
566 if (VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Top)
567 boundsCenter.y -= rect.size.y * .5f;
568 else if (VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Bottom)
569 boundsCenter.y += rect.size.y * .5f;
570
571 VuoSceneObject_translate((VuoSceneObject)child, (VuoPoint3d){boundsCenter.x, boundsCenter.y, 0});
572
573 VuoTransform parentTransform = childTransform;
574 parentTransform.translation = parentTranslation;
575
577
580
582
583 return parent;
584}
585
589VuoRectangle VuoLayer_getBoundingRectangle(VuoLayer layer, VuoInteger viewportWidth, VuoInteger viewportHeight, float backingScaleFactor)
590{
591 return VuoLayer_getBoundingRectangleWithSceneObject((VuoSceneObject)layer, viewportWidth, viewportHeight, backingScaleFactor);
592}
593
598{
600}
601
607{
609}
610
616{
618}
619
624char * VuoLayer_getSummary(const VuoLayer value)
625{
627}