/** * Performs a depth-first search of the scenegraph. * Returns the first camera whose name contains @c nameToMatch (or, if @c nameToMatch is emptystring, just returns the first camera), * with its transform altered to incorporate the transforms of its ancestor objects. * Output paramater @c foundCamera indicates whether a camera was found. * If no camera was found, returns VuoSceneObject_makeDefaultCamera(). */ VuoSceneObject VuoSceneObject_findCamera(VuoSceneObject so, VuoText nameToMatch, bool *foundCamera) { float localModelviewMatrix[16]; VuoTransform_getMatrix(VuoTransform_makeIdentity(), localModelviewMatrix); return VuoSceneObject_findCameraInternal(so, nameToMatch, foundCamera, localModelviewMatrix); }
/** * Returns a column-major matrix of 16 values that transforms a 1x1 quad so that it renders the specified image at real (pixel-perfect) size. */ void VuoTransform_getBillboardMatrix(VuoInteger imageWidth, VuoInteger imageHeight, VuoReal translationX, VuoReal translationY, VuoInteger viewportWidth, VuoInteger viewportHeight, float *billboardMatrix) { VuoTransform_getMatrix(VuoTransform_makeIdentity(), billboardMatrix); // Apply scale to make the image appear at real size (1:1). billboardMatrix[0] = 2. * imageWidth/viewportWidth; billboardMatrix[5] = billboardMatrix[0] * imageHeight/imageWidth; // Apply 2D translation. // Align the translation to pixel boundaries billboardMatrix[12] = floor((translationX+1.)/2.*viewportWidth) / ((float)viewportWidth) * 2. - 1.; billboardMatrix[13] = floor((translationY+1.)/2.*viewportWidth) / ((float)viewportWidth) * 2. - 1.; // Account for odd-dimensioned image billboardMatrix[12] += (imageWidth % 2 ? (1./viewportWidth) : 0); billboardMatrix[13] -= (imageHeight % 2 ? (1./viewportWidth) : 0); // Account for odd-dimensioned viewport billboardMatrix[13] += (viewportWidth % 2 ? (1./viewportWidth) : 0); billboardMatrix[13] -= (viewportHeight % 2 ? (1./viewportWidth) : 0); }
/** * Finds and returns all the lights in the scene. * * If there are multiple ambient lights, returns the weighted (by alpha) average color and summed brightness. * * If there are no lights in the scene, returns some default lights. */ void VuoSceneObject_findLights(VuoSceneObject so, VuoColor *ambientColor, float *ambientBrightness, VuoList_VuoSceneObject *pointLights, VuoList_VuoSceneObject *spotLights) { VuoList_VuoColor ambientColors = VuoListCreate_VuoColor(); VuoRetain(ambientColors); *ambientBrightness = 0; *pointLights = VuoListCreate_VuoSceneObject(); *spotLights = VuoListCreate_VuoSceneObject(); float localModelviewMatrix[16]; VuoTransform_getMatrix(VuoTransform_makeIdentity(), localModelviewMatrix); VuoSceneObject_findLightsRecursive(so, localModelviewMatrix, ambientColors, ambientBrightness, *pointLights, *spotLights); if (!VuoListGetCount_VuoColor(ambientColors) && !VuoListGetCount_VuoSceneObject(*pointLights) && !VuoListGetCount_VuoSceneObject(*spotLights)) { *ambientColor = VuoColor_makeWithRGBA(1,1,1,1); *ambientBrightness = 0.05; // https://en.wikipedia.org/wiki/Three-point_lighting VuoSceneObject keyLight = VuoSceneObject_makePointLight(VuoColor_makeWithRGBA(1,1,1,1), .70, VuoPoint3d_make(-1,1,1), 5, .5); VuoListAppendValue_VuoSceneObject(*pointLights, keyLight); VuoSceneObject fillLight = VuoSceneObject_makePointLight(VuoColor_makeWithRGBA(1,1,1,1), .2, VuoPoint3d_make(.5,0,1), 5, 0); VuoListAppendValue_VuoSceneObject(*pointLights, fillLight); VuoSceneObject backLight = VuoSceneObject_makePointLight(VuoColor_makeWithRGBA(1,1,1,1), .15, VuoPoint3d_make(1,.75,-.5), 5, 0); VuoListAppendValue_VuoSceneObject(*pointLights, backLight); } else *ambientColor = VuoColor_average(ambientColors); VuoRelease(ambientColors); }
/** * @ingroup VuoTransform * Decodes the JSON object @c js to create a new value. * * @eg{"identity"} * @eg{ * { * "quaternionRotation" = [0,0,0,1], * "translation" = [0,0,0], * "scale" = [1,1,1] * } * } * @eg{ * { * "eulerRotation" = [0,0,0], * "translation" = [0,0,0], * "scale" = [1,1,1] * } * } */ VuoTransform VuoTransform_valueFromJson(json_object *js) { VuoTransform t = VuoTransform_makeIdentity(); json_object *o = NULL; if (json_object_object_get_ex(js, "target", &o)) { VuoPoint3d target; target.x = json_object_get_double(json_object_array_get_idx(o,0)); target.y = json_object_get_double(json_object_array_get_idx(o,1)); target.z = json_object_get_double(json_object_array_get_idx(o,2)); VuoPoint3d position = VuoPoint3d_make(0,0,0); if (json_object_object_get_ex(js, "translation", &o)) { position.x = json_object_get_double(json_object_array_get_idx(o,0)); position.y = json_object_get_double(json_object_array_get_idx(o,1)); position.z = json_object_get_double(json_object_array_get_idx(o,2)); } VuoPoint3d upDirection = VuoPoint3d_make(0,1,0); if (json_object_object_get_ex(js, "upDirection", &o)) { upDirection.x = json_object_get_double(json_object_array_get_idx(o,0)); upDirection.y = json_object_get_double(json_object_array_get_idx(o,1)); upDirection.z = json_object_get_double(json_object_array_get_idx(o,2)); } return VuoTransform_makeFromTarget(position, target, upDirection); } if (json_object_object_get_ex(js, "quaternionRotation", &o)) { t.type = VuoTransformTypeQuaternion; VuoPoint4d q; q.x = json_object_get_double(json_object_array_get_idx(o,0)); q.y = json_object_get_double(json_object_array_get_idx(o,1)); q.z = json_object_get_double(json_object_array_get_idx(o,2)); q.w = json_object_get_double(json_object_array_get_idx(o,3)); t = VuoTransform_makeQuaternion(VuoPoint3d_make(0,0,0), q, VuoPoint3d_make(0,0,0)); } else if (json_object_object_get_ex(js, "eulerRotation", &o)) { t.type = VuoTransformTypeEuler; VuoPoint3d e; e.x = json_object_get_double(json_object_array_get_idx(o,0)); e.y = json_object_get_double(json_object_array_get_idx(o,1)); e.z = json_object_get_double(json_object_array_get_idx(o,2)); t = VuoTransform_makeEuler(VuoPoint3d_make(0,0,0), e, VuoPoint3d_make(0,0,0)); } if (json_object_object_get_ex(js, "translation", &o)) { t.translation.x = json_object_get_double(json_object_array_get_idx(o,0)); t.translation.y = json_object_get_double(json_object_array_get_idx(o,1)); t.translation.z = json_object_get_double(json_object_array_get_idx(o,2)); } if (json_object_object_get_ex(js, "scale", &o)) { t.scale.x = json_object_get_double(json_object_array_get_idx(o,0)); t.scale.y = json_object_get_double(json_object_array_get_idx(o,1)); t.scale.z = json_object_get_double(json_object_array_get_idx(o,2)); } return t; }
* vuo.transform.combine node implementation. * * @copyright Copyright © 2012–2015 Kosada Incorporated. * This code may be modified and distributed under the terms of the MIT License. * For more information, see http://vuo.org/license. */ #include "node.h" VuoModuleMetadata({ "title" : "Combine Transforms", "keywords" : [ "composite", "product", "multiply", "merge" ], "version" : "1.0.0", "node": { "exampleCompositions" : [ "TiltAndOrbitCube.vuo" ] } }); void nodeEvent ( VuoInputData(VuoList_VuoTransform) transforms, VuoOutputData(VuoTransform) composite ) { *composite = VuoTransform_makeIdentity(); unsigned long transformCount = VuoListGetCount_VuoTransform(transforms); for (unsigned long i = 1; i <= transformCount; ++i) *composite = VuoTransform_composite(*composite, VuoListGetValue_VuoTransform(transforms, i)); }