Exemplo n.º 1
0
/**
 * Helper for @ref VuoSceneObject_findLights.
 */
static void VuoSceneObject_findLightsRecursive(VuoSceneObject so, float modelviewMatrix[16], VuoList_VuoColor ambientColors, float *ambientBrightness, VuoList_VuoSceneObject pointLights, VuoList_VuoSceneObject spotLights)
{
	switch (so.type)
	{
		case VuoSceneObjectType_AmbientLight:
			VuoListAppendValue_VuoColor(ambientColors, so.lightColor);
			*ambientBrightness += so.lightBrightness;
			return;
		case VuoSceneObjectType_PointLight:
		{
			float localModelviewMatrix[16];
			VuoTransform_getMatrix(so.transform, localModelviewMatrix);
			float compositeModelviewMatrix[16];
			VuoTransform_multiplyMatrices4x4(localModelviewMatrix, modelviewMatrix, compositeModelviewMatrix);
			so.transform = VuoTransform_makeFromMatrix4x4(compositeModelviewMatrix);

			VuoListAppendValue_VuoSceneObject(pointLights, so);
			return;
		}
		case VuoSceneObjectType_Spotlight:
		{
			float localModelviewMatrix[16];
			VuoTransform_getMatrix(so.transform, localModelviewMatrix);
			float compositeModelviewMatrix[16];
			VuoTransform_multiplyMatrices4x4(localModelviewMatrix, modelviewMatrix, compositeModelviewMatrix);
			so.transform = VuoTransform_makeFromMatrix4x4(compositeModelviewMatrix);

			VuoListAppendValue_VuoSceneObject(spotLights, so);
			return;
		}
		default:
			break;
	}

	if (so.childObjects)
	{
		float localModelviewMatrix[16];
		VuoTransform_getMatrix(so.transform, localModelviewMatrix);
		float compositeModelviewMatrix[16];
		VuoTransform_multiplyMatrices4x4(localModelviewMatrix, modelviewMatrix, compositeModelviewMatrix);

		unsigned long childObjectCount = VuoListGetCount_VuoSceneObject(so.childObjects);
		for (unsigned long i = 1; i <= childObjectCount; ++i)
		{
			VuoSceneObject childObject = VuoListGetValue_VuoSceneObject(so.childObjects, i);
			VuoSceneObject_findLightsRecursive(childObject, compositeModelviewMatrix, ambientColors, ambientBrightness, pointLights, spotLights);
		}
	}
}
Exemplo n.º 2
0
/**
 * 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);
}
Exemplo n.º 3
0
/**
 * 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);
}
Exemplo n.º 4
0
/**
 * @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));
}
Exemplo n.º 5
0
/**
 * Helper for @ref VuoSceneObject_apply.
 */
VuoSceneObject VuoSceneObject_findCameraInternal(VuoSceneObject so, VuoText nameToMatch, bool *foundCamera, float modelviewMatrix[16])
{
	float localModelviewMatrix[16];
	VuoTransform_getMatrix(so.transform, localModelviewMatrix);
	float compositeModelviewMatrix[16];
	VuoTransform_multiplyMatrices4x4(localModelviewMatrix, modelviewMatrix, compositeModelviewMatrix);

	if ((so.type == VuoSceneObjectType_PerspectiveCamera
	  || so.type == VuoSceneObjectType_StereoCamera
	  || so.type == VuoSceneObjectType_OrthographicCamera)
	  && strstr(so.name,nameToMatch))
	{
		*foundCamera = true;
		so.transform = VuoTransform_makeFromMatrix4x4(compositeModelviewMatrix);
		return so;
	}

	if (so.childObjects)
	{
		unsigned long childObjectCount = VuoListGetCount_VuoSceneObject(so.childObjects);
		for (unsigned long i = 1; i <= childObjectCount; ++i)
		{
			VuoSceneObject childObject = VuoListGetValue_VuoSceneObject(so.childObjects, i);
			bool foundChildCamera;
			VuoSceneObject childCamera = VuoSceneObject_findCameraInternal(childObject, nameToMatch, &foundChildCamera, compositeModelviewMatrix);
			if (foundChildCamera)
			{
				*foundCamera = true;
				return childCamera;
			}
			else
			{
				VuoSceneObject_retain(childCamera);
				VuoSceneObject_release(childCamera);
			}
		}
	}

	*foundCamera = false;
	return VuoSceneObject_makeDefaultCamera();
}
Exemplo n.º 6
0
/**
 * 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);
}
Exemplo n.º 7
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);
}