/** * Outputs the inverse of `matrix` * (which is assumed to consist of a rotation followed by a scale followed by a translation, * like the output of @ref VuoTransform_getMatrix), * such that `outputInvertedMatrix * matrix = identityMatrix`. */ void VuoTransform_invertMatrix4x4(const float *matrix, float *outputInvertedMatrix) { float inverseTranslation[16]; VuoTransform_getMatrix(VuoTransform_makeEuler( VuoPoint3d_make(-matrix[12], -matrix[13], -matrix[14]), VuoPoint3d_make(0,0,0), VuoPoint3d_make(1,1,1)), inverseTranslation); // Transpose the rotation/scale part of the input matrix (which undoes the rotation), and set the last row/column to identity. float inverseRotation[16] = { matrix[0], matrix[4], matrix[8], 0, matrix[1], matrix[5], matrix[9], 0, matrix[2], matrix[6], matrix[10], 0, 0, 0, 0, 1 }; float inverseScale[16]; VuoTransform_getMatrix(VuoTransform_makeEuler( VuoPoint3d_make(0,0,0), VuoPoint3d_make(0,0,0), VuoPoint3d_make( 1/VuoPoint3d_magnitude(VuoPoint3d_make(matrix[0], matrix[1], matrix[2])), 1/VuoPoint3d_magnitude(VuoPoint3d_make(matrix[4], matrix[5], matrix[6])), 1/VuoPoint3d_magnitude(VuoPoint3d_make(matrix[8], matrix[9], matrix[10])))), inverseScale); VuoTransform_multiplyMatrices4x4(inverseTranslation, inverseRotation, outputInvertedMatrix); VuoTransform_multiplyMatrices4x4(outputInvertedMatrix, inverseScale, outputInvertedMatrix); // Apply inverseScale a second time, since inverseRotation includes forward scale. VuoTransform_multiplyMatrices4x4(outputInvertedMatrix, inverseScale, outputInvertedMatrix); }
/** * Creates a 3D transform from a 2D transform. */ VuoTransform VuoTransform_makeFrom2d(VuoTransform2d transform2d) { VuoPoint3d center3d = VuoPoint3d_make(transform2d.translation.x, transform2d.translation.y, 0); VuoPoint3d rotation3d = VuoPoint3d_make(0, 0, transform2d.rotation); VuoPoint3d scale3d = VuoPoint3d_make(transform2d.scale.x, transform2d.scale.y, 1); return VuoTransform_makeEuler(center3d, rotation3d, scale3d); }
/** * @ingroup VuoSceneObject * Returns a point light (uniform emission in all directions). * * @param color The light's color. * @param brightness The light's brightness multiplier (typically between 0 and 1). * @param position The light's position. * @param range The distance (in local coordinates) the light reaches. * @param sharpness The sharpness of the light's distance falloff. 0 means the light starts fading at distance 0 and ends at 2*lightRange. 1 means the falloff is instant. */ VuoSceneObject VuoSceneObject_makePointLight(VuoColor color, float brightness, VuoPoint3d position, float range, float sharpness) { VuoSceneObject o = VuoSceneObject_makeEmpty(); o.type = VuoSceneObjectType_PointLight; o.lightColor = color; o.lightBrightness = brightness; o.lightRange = range; o.lightSharpness = MAX(MIN(sharpness,1),0); o.transform = VuoTransform_makeEuler(position, VuoPoint3d_make(0,0,0), VuoPoint3d_make(1,1,1)); return o; }
/** * Returns a scene object that renders a quad with the specified shader. * * The quad includes normals, tangents, or bitangents. * * @param shader The shader used to render the object. * @param center The object's center, specified in scene coordinates. * @param rotation The object's rotation, specified in degrees. * @param width The object's width, specified in scene coordinates. * @param height The object's height, specified in scene coordinates. * @return The quad scene object. * * @threadAnyGL */ VuoSceneObject VuoSceneObject_makeQuadWithNormals(VuoShader shader, VuoPoint3d center, VuoPoint3d rotation, VuoReal width, VuoReal height) { return VuoSceneObject_make( VuoMesh_makeQuad(), shader, VuoTransform_makeEuler( center, VuoPoint3d_multiply(rotation, M_PI/180.), VuoPoint3d_make(width,height,1) ), NULL ); }
/** * @ingroup VuoTransform * Start with an object pointing rightward (increasing X axis). * This function returns a unit vector representing the direction * a rightward-pointing object (+x axis) would be pointing after being transformed by @c transform. */ VuoPoint3d VuoTransform_getDirection(const VuoTransform transform) { // Make a new transform with only the rotational component. VuoTransform r; if (transform.type == VuoTransformTypeEuler) r = VuoTransform_makeEuler(VuoPoint3d_make(0,0,0), transform.rotationSource.euler, VuoPoint3d_make(1,1,1)); else r = VuoTransform_makeQuaternion(VuoPoint3d_make(0,0,0), transform.rotationSource.quaternion, VuoPoint3d_make(1,1,1)); float m[16]; VuoTransform_getMatrix(r, m); return VuoTransform_transformPoint(m, VuoPoint3d_make(1,0,0)); }
/** * Returns a perspective camera at (0,0,1), facing along -z, 90 degree FOV, and clip planes at 0.1 and 10.0. */ VuoSceneObject VuoSceneObject_makeDefaultCamera(void) { VuoTransform transform = VuoTransform_makeEuler( VuoPoint3d_make(0,0,1), VuoPoint3d_make(0,0,0), VuoPoint3d_make(1,1,1) ); return VuoSceneObject_makePerspectiveCamera( VuoText_make("default camera"), transform, 90, 0.1, 10.0 ); }
/** * Returns a scene object consisting of 6 child objects (square quads), each with its own shader. */ VuoSceneObject VuoSceneObject_makeCube(VuoTransform transform, VuoShader frontShader, VuoShader leftShader, VuoShader rightShader, VuoShader backShader, VuoShader topShader, VuoShader bottomShader) { VuoList_VuoSceneObject cubeChildObjects = VuoListCreate_VuoSceneObject(); VuoMesh quadMesh = VuoMesh_makeQuad(); // Front Face { VuoSceneObject so = VuoSceneObject_make( quadMesh, frontShader, VuoTransform_makeEuler(VuoPoint3d_make(0,0,.5), VuoPoint3d_make(0,0,0), VuoPoint3d_make(1,1,1)), NULL ); VuoListAppendValue_VuoSceneObject(cubeChildObjects, so); } // Left Face { VuoSceneObject so = VuoSceneObject_make( quadMesh, leftShader, VuoTransform_makeEuler(VuoPoint3d_make(-.5,0,0), VuoPoint3d_make(0,-M_PI/2.,0), VuoPoint3d_make(1,1,1)), NULL ); VuoListAppendValue_VuoSceneObject(cubeChildObjects, so); } // Right Face { VuoSceneObject so = VuoSceneObject_make( quadMesh, rightShader, VuoTransform_makeEuler(VuoPoint3d_make(.5,0,0), VuoPoint3d_make(0,M_PI/2.,0), VuoPoint3d_make(1,1,1)), NULL ); VuoListAppendValue_VuoSceneObject(cubeChildObjects, so); } // Back Face { VuoSceneObject so = VuoSceneObject_make( quadMesh, backShader, VuoTransform_makeEuler(VuoPoint3d_make(0,0,-.5), VuoPoint3d_make(0,M_PI,0), VuoPoint3d_make(1,1,1)), NULL ); VuoListAppendValue_VuoSceneObject(cubeChildObjects, so); } // Top Face { VuoSceneObject so = VuoSceneObject_make( quadMesh, topShader, VuoTransform_makeEuler(VuoPoint3d_make(0,.5,0), VuoPoint3d_make(-M_PI/2.,0,0), VuoPoint3d_make(1,1,1)), NULL ); VuoListAppendValue_VuoSceneObject(cubeChildObjects, so); } // Bottom Face { VuoSceneObject so = VuoSceneObject_make( quadMesh, bottomShader, VuoTransform_makeEuler(VuoPoint3d_make(0,-.5,0), VuoPoint3d_make(M_PI/2.,0,0), VuoPoint3d_make(1,1,1)), NULL ); VuoListAppendValue_VuoSceneObject(cubeChildObjects, so); } return VuoSceneObject_make(NULL, NULL, transform, cubeChildObjects); }
/** * @file * vuo.type.translate.point3d.transform node implementation. * * @copyright Copyright © 2012–2014 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" : "Convert 3D Point to Translation", "keywords" : [ "position", "matrix", "trs", "angle", "axis" ], "version" : "1.0.0" }); void nodeEvent ( VuoInputData(VuoPoint3d, {"default":{"x":0, "y":0, "z":0}}) translation, VuoOutputData(VuoTransform) transform ) { *transform = VuoTransform_makeEuler( translation, VuoPoint3d_make(0.,0.,0.), VuoPoint3d_make(1.,1.,1.) ); }
"node": { "isInterface" : false, "exampleCompositions" : [ "Compare4Cameras.vuo", "SwitchCameras.vuo" ] } }); void nodeEvent ( VuoInputData(VuoText, {"default":"camera"}) name, VuoInputData(VuoPoint3d, {"default":{"x":0.0,"y":0.0,"z":1.0}, "suggestedStep":{"x":0.1,"y":0.1,"z":0.1}}) position, VuoInputData(VuoPoint3d, {"default":{"x":0.0,"y":0.0,"z":0.0}, "suggestedMin":{"x":0.0,"y":0.0,"z":0.0}, "suggestedMax":{"x":360.0,"y":360.0,"z":360.0}, "suggestedStep":{"x":15.0,"y":15.0,"z":15.0}}) rotation, VuoInputData(VuoReal, {"default":90.0, "suggestedMin":0.01, "suggestedMax":179.9, "suggestedStep":1.0}) fieldOfView, VuoInputData(VuoReal, {"default":0.1, "suggestedMin":0.01, "suggestedStep":1.0}) distanceMin, VuoInputData(VuoReal, {"default":10.0, "suggestedMin":0.01, "suggestedStep":1.0}) distanceMax, VuoOutputData(VuoSceneObject) object ) { VuoTransform transform = VuoTransform_makeEuler( position, VuoPoint3d_multiply(rotation, M_PI/180.f), VuoPoint3d_make(1,1,1) ); *object = VuoSceneObject_makePerspectiveCamera( name, transform, fieldOfView, distanceMin, distanceMax ); }
/** * @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; }
/** * @ingroup VuoTransform * Creates a @c VuoTransform with no effect. */ VuoTransform VuoTransform_makeIdentity(void) { return VuoTransform_makeEuler(VuoPoint3d_make(0,0,0), VuoPoint3d_make(0,0,0), VuoPoint3d_make(1,1,1)); }
* @file * vuo.transform.make node implementation. * * @copyright Copyright © 2012–2014 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" : "Make 3D Transform", "keywords" : [ "Euler", "translation", "rotation", "scale", "shift", "move", "position", "angle", "yaw", "pitch", "roll", "axis", "size", "grow", "shrink" ], "version" : "1.0.0", "node": { "exampleCompositions" : [ ] } }); void nodeEvent ( VuoInputData(VuoPoint3d, {"default":{"x":0,"y":0,"z":0},"suggestedStep":{"x":0.1,"y":0.1,"z":0.1}}) translation, VuoInputData(VuoPoint3d, {"default":{"x":0,"y":0,"z":0},"suggestedMin":{"x":0,"y":0,"z":0},"suggestedMax":{"x":360,"y":360,"z":360},"suggestedStep":{"x":15,"y":15,"z":15}}) rotation, VuoInputData(VuoPoint3d, {"default":{"x":1,"y":1,"z":1},"suggestedStep":{"x":0.1,"y":0.1,"z":0.1}}) scale, VuoOutputData(VuoTransform) transform ) { *transform = VuoTransform_makeEuler(translation, VuoPoint3d_multiply(rotation, M_PI/180.), scale); }
#include "node.h" VuoModuleMetadata({ "title" : "Make Spotlight", "keywords" : [ "draw", "opengl", "scenegraph", "graphics", "directional", "lighting", "point", "source" ], "version" : "1.0.0", "node": { "exampleCompositions" : [ "AimFlashlight.vuo", "CompareLights.vuo" ] } }); void nodeEvent ( VuoInputData(VuoColor,{"default":{"r":1.,"g":1.,"b":1.,"a":1.}}) color, VuoInputData(VuoReal, {"default":1.0, "suggestedMin":0., "suggestedMax":1., "suggestedStep":0.1}) brightness, VuoInputData(VuoPoint3d, {"default":{"x":0.,"y":0.,"z":1.}, "suggestedStep":{"x":0.1,"y":0.1,"z":0.1}}) position, VuoInputData(VuoPoint2d, {"default":{"x":0.,"y":0.}, "suggestedMin":{"x":0.0,"y":0.0}, "suggestedMax":{"x":360.0,"y":360.0}, "suggestedStep":{"x":15.0,"y":15.0}}) rotation, VuoInputData(VuoReal, {"default":30., "suggestedMin":0., "suggestedMax":180., "suggestedStep":15.}) cone, VuoInputData(VuoReal, {"default":10., "suggestedMin":0., "suggestedStep":0.1}) range, VuoInputData(VuoReal, {"default":0.9, "suggestedMin":0., "suggestedMax":1., "suggestedStep":0.1}) sharpness, VuoOutputData(VuoSceneObject) object ) { // For vector (1,0,0), Euler rotations about the x, y, and z axes respectively mean roll, yaw, and pitch. // Since spotlights are unaffected by roll, this node only takes 2 rotational values. VuoPoint3d rotation3d = VuoPoint3d_make(0, rotation.x+90., rotation.y); *object = VuoSceneObject_makeSpotlight(color, brightness, VuoTransform_makeEuler(position, VuoPoint3d_multiply(rotation3d, M_PI/180.), VuoPoint3d_make(1,1,1)), cone*M_PI/180., range, sharpness); }