User Tools

Site Tools


Texture Modifier

Summary

Below is an example demonstrating how you can create texture modifiers for material properties that are mappable and have images assigned to them, and cause the color of those images to toggle between normal/inverted.

API Areas of Interest

Example

Material_Property_Texture_Modifiers.dsa
// Define an anonymous function;
// serves as our main loop,
// limits the scope of variables
(function(){
 
	/*********************************************************************/
	// Boolean : A function for testing whether or not a QObject instance
	// inherits one of a list of types
	function inheritsType( oObject, aTypeNames )
	{
		// If the object does not define the 'inherits' function
		if( !oObject || typeof( oObject.inherits ) != "function" ){
			// We are done... it is not a QObject
			return false;
		}
 
		// Iterate over the list of type names
		for( var i = 0, nTypes = aTypeNames.length; i < nTypes; i += 1 ){
			// If the object does not inherit the 'current' type
			if( !oObject.inherits( aTypeNames[i] ) ){
				// Next!!
				continue;
			}
 
			// Return the result
			return true;
		}
 
		// Return the result
		return false;
	};
 
	/*********************************************************************/
	// DzTextureModifier : A function for getting/creating a texture modifier
	// for a property that has a map
	function getTextureModifier( oProperty, bCreate )
	{
		// Initialize
		var oTextureModifier = null;
 
		// If the application version is less than 4.6.4.80
		if( App.version64 < 0x0004000600040050 ){
			// We are done... DzTextureModifier did not exist
			return oTextureModifier;
		}
 
		// If we have a numeric property that can be, and is, mapped
		if( inheritsType( oProperty, [ "DzNumericProperty" ] )
		&& oProperty.isMappable()
		&& oProperty.isMapped() ){
			// Get the texture modifier
			oTextureModifier = oProperty.getTextureModifier();
 
			// If we do not have a texture modifier and want to create one
			if( !oTextureModifier && bCreate ){
				// Create a texture modifier
				oTextureModifier = new DzTextureModifier();
				// Assign the modifier to the property
				oProperty.setTextureModifier( oTextureModifier );
			}
		// If we have an image property and it has a texture assigned
		} else if( inheritsType( oProperty, [ "DzImageProperty" ] )
		&& oProperty.getValue() ){
			// Get the texture modifier
			oTextureModifier = oProperty.getTextureModifier();
 
			// If we do not have a texture modifier and want to create one
			if( !oTextureModifier && bCreate ){
				// Create a texture modifier
				oTextureModifier = new DzTextureModifier();
				// Assign the modifier to the property
				oProperty.setTextureModifier( oTextureModifier );
			}
		}
 
		// Return the result
		return oTextureModifier;
	};
 
	/*********************************************************************/
	// Array<DzProperty> : A function for getting a list of the properties in a group
	function getGroupProperties( oGroup, bTraverse, bRecurse )
	{
		// Declare an array to hold properties
		var aProperties = [];
 
		// If a group is not passed in
		if( !oGroup ){
			// We are done, return an empty array
			return aProperties;
		}
 
		// Get the number of proeprties in the group
		var nProperties = oGroup.getNumProperties();
		// Pre-size the properties array
		aProperties = new Array( nProperties );
		// Iterate over the properties, setting each element in the array
		for( var i = 0; i < nProperties; i += 1 ){
			// Assign the property to the position in the array
			aProperties[ i ] = oGroup.getProperty( i );
		}
 
		// If we are recursing
		if( bRecurse ){
			// Concatenate the properties array from child groups
			aProperties = aProperties.concat(
				getGroupProperties( oGroup.getFirstChild(), true, bRecurse ) );
		}
 
		// If we are traversing
		if( bTraverse ){
			// Concatenate the properties array from sibling groups
			aProperties = aProperties.concat(
				getGroupProperties( oGroup.getNextSibling(), bTraverse, bRecurse ) );
		}
 
		// Return the array of properties
		return aProperties;
	};
 
	/*********************************************************************/
	// Array<DzProperty> : A function for getting the list properties for an element
	function getElementProperties( oElement, bTraverse, bRecurse )
	{
		// Get the property group tree for the element
		var oPropertyGroupTree = oElement.getPropertyGroups();
 
		// If the application version is 4.9.4.101 or newer and we want all properties
		if( App.version64 >= 0x0004000900040065 && bTraverse && bRecurse ){
			// Return the properties for the element
			return oPropertyGroupTree.getAllProperties();
		}
 
		// Get the first group in the tree
		var oPropertyGroup = oPropertyGroupTree.getFirstChild();
		// Return the properties for the element
		return getGroupProperties( oPropertyGroup, bTraverse, bRecurse );
	};
 
	/*********************************************************************/
	// DzProperty : A function for finding a property associated with an element
	function findElementProperty( oElement, sProperty, bUseLabel )
	{
		// Declare a working variable
		var oProperty;
 
		// Create a scene helper object
		var oSceneHelper = new DzSceneHelper();
 
		// If we are using the label
		if( bUseLabel ){
			// If DzSceneHelper::findPropertyByLabel() exists
			if( typeof( oSceneHelper.findPropertyByLabel ) == "function" ){
				// Get the property on the element with the label
				oProperty = oSceneHelper.findPropertyByLabel( sProperty, oElement );
			// If the element is a node and DzSceneHelper::findPropertyOnNodeByLabel() exists
			} else if( inheritsType( oElement, ["DzNode"] &&
			typeof( oSceneHelper.findPropertyOnNodeByLabel ) == "function" ) ){
				// Get the property on the node with the label
				oProperty = oSceneHelper.findPropertyOnNodeByLabel( sProperty, oElement );
			}
		// If we are NOT using the label
		} else {
			// Find the property by internal name on the node
			oProperty = oSceneHelper.findPropertyByInternalName( sProperty, oElement );
			// If DzSceneHelper::findPropertyByLabel() exists
			if( typeof( oSceneHelper.findPropertyByInternalName ) == "function" ){
				// Get the property on the element with the label
				oProperty = oSceneHelper.findPropertyByInternalName( sProperty, oElement );
			// If the element is a node and DzSceneHelper::findPropertyOnNodeByLabel() exists
			} else if( inheritsType( oElement, ["DzNode"] &&
			typeof( oSceneHelper.findPropertyOnNodeByInternalName ) == "function" ) ){
				// Get the property on the node with the label
				oProperty = oSceneHelper.findPropertyOnNodeByInternalName( sProperty, oElement );
			}
		}
 
		// Clean up; do not leak memory
		oSceneHelper.deleteLater();
 
		// If we found a property
		if( oProperty ){
			// We are done, return it
			return oProperty;
		}
 
		// Whether or not to use optimizations; 4.7.1.44 or newer
		var bUseOptimization = (App.version64 >= 0x000400070001002c);
 
		// If the application version is 4.7.1.44 or newer and we are not using
		// the label to find, or the application version is 4.11.0.166 or newer
		if( (bUseOptimization && !bUseLabel) ||
			App.version64 >= 0x0004000b000000a6 ){
			// Get the property group tree for the element
			var oPropertyGroupTree = oElement.getPropertyGroups();
 
			// If we are using the label
			if( bUseLabel ){
				// Attempt to find the property
				oProperty = oPropertyGroupTree.findPropertyByLabel( sProperty );
			// If we are not using the label
			} else {
				// Attempt to find the property
				oProperty = oPropertyGroupTree.findProperty( sProperty );
			}
 
			// If we found a property
			if( oProperty ){
				// We are done, return it
				return oProperty;
			}
		// Otherwise
		} else {
			// Get the properties of the element
			var aProperties = getElementProperties( oElement, true, true );
			// Iterate over the properties
			for( var i = 0; i < aProperties.length; i += 1 ){
				// Get the 'current' property
				oProperty = aProperties[i];
 
				// If we are using the label
				if( bUseLabel ){
					// If the label of the property is the one we are looking for
					if( oProperty.getLabel() == sProperty ){
						// We are done, return it
						return oProperty;
					}
				// If we are not using the label
				} else {
					// If the name of the property is the one we are looking for
					if( oProperty.name == sProperty ){
						// We are done, return it
						return oProperty;
					}				
				}
			}
		}
 
		return null;
	};
 
	/*********************************************************************/
	// Array<DzProperty> : A function for getting the list properties for an element
	function getElementPropertiesInPath( oElement, sPath, bRecurse )
	{
		// If the path is empty
		if( !sPath ){
			// Return the properties for the element
			return getElementProperties( oElement, true, bRecurse );
		}
 
		// Initialize
		var oGroup = oElement.getPropertyGroups();
		var sName = "";
		var nIdx = -1;
		var sSubPath = sPath;
 
		// While the remaining path is not empty
		while( oGroup && !sSubPath.isEmpty() ){
			// Get the index of the first slash
			nIdx = sSubPath.indexOf( "/" );
			// If a slash was not found
			if( nIdx < 0 ){
				// The group name is the path
				sName = sSubPath;
				// Break the loop on the next evaluation
				sSubPath = "";
			// If a slash was found
			} else {
				// The group name is before the slash
				sName = sSubPath.left( nIdx );
				// Get the remaining path
				sSubPath = sSubPath.right( sSubPath.length - nIdx - 1 );
			}
 
			// Get the sub group
			oGroup = oGroup ? oGroup.findChild( sName ) : null;
		}
 
		// Return the properties for the element
		return getGroupProperties( oGroup, false, bRecurse );
	};
 
	/*********************************************************************/
	// DzNode : A function for getting the root of a node
	function getRootNode( oNode )
	{
		// If we have a node and it is a bone
		if( oNode && inheritsType( oNode, ["DzBone"] ) ){
			// We want the skeleton
			return oNode.getSkeleton();
		}
 
		// Return the original node
		return oNode;
	};
 
	/*********************************************************************/
	// DzObject : A function for getting the object for a node
	function getObjectForNode( oNode, bRoot )
	{
		// Get the node
		var oContextNode = bRoot ? getRootNode( oNode ) : oNode;
		// If we do not have a root node
		if( !oContextNode ){
			// We are done...
			return null;
		}
 
		// Get the object of the root node
		var oObject = oContextNode.getObject();
		// If we do not have an object
		if( !oObject ){
			// We are done...
			return null;
		}
 
		// Return the object
		return oObject;
	};
 
	/*********************************************************************/
	// DzShape : A function for getting the shape for a node
	function getShapeForNode( oNode, bRoot )
	{
		// Get the object of the node
		var oObject = getObjectForNode( oNode, bRoot );
		// If we do not have an object
		if( !oObject ){
			// We are done...
			return null;
		}
 
		// Get the shape of the root node
		var oShape = oObject.getCurrentShape();
		// If we do not have a shape
		if( !oShape ){
			// We are done...
			return null;
		}
 
		// Return the shape
		return oShape;
	};
 
	/*********************************************************************/
	// Get the primary selection
	var oNode = Scene.getPrimarySelection();
	// If nothing is selected
	if( !oNode ){
		// We are done...
		return;
	}
 
	// Get the current shape for the object
	var oShape = getShapeForNode( oNode, true );
	// If we do not have a shape
	if( !oShape ){
		// We are done..
		return;
	}
 
	// Get the selected materials
	var aMaterials = oShape.getAllSelectedMaterials();
	// If we do not have any selected materials
	if( aMaterials.length < 1 ){
		// Get all of the materials
		aMaterials = oShape.getAllMaterials();
	}
 
	// Define the property(ies) we are looking for
	var sProperty = "Diffuse Color";
	var sPropertyPath = "Base/Diffuse/Reflection";
 
	// Initialize a list of properties
	var aProperties = [];
 
	// Declare working variables
	var oMaterial,
	var oProperty;
 
	// Iterate over the materials
	for( var i = 0; i < aMaterials.length; i += 1 ){
		// Get the 'current' material
		oMaterial = aMaterials[ i ];
 
		// If a property name is defined
		if( !sProperty.isEmpty() ){
			// Find the property by name on the material
			oProperty = findElementProperty( oMaterial, sProperty, false );
			// If the property is found
			if( oProperty ){
				// Collect the property
				aProperties.push( oProperty );
			}
		// If a property path is defined
		} else if( !sPropertyPath.isEmpty() ){
			// Collect the properties at the specified path on the material
			aProperties = aProperties.concat( getElementPropertiesInPath( oMaterial, sPropertyPath, true ) );
		// If neither a property name nor a property path is defined
		} else {
			// Collect the properties on the material
			aProperties = aProperties.concat( getElementProperties( oMaterial, true, true ) );
		}
	}
 
	// Declare working variable
	var oTextureModifier;
 
	// Iterate over the collected properties
	for( var i = 0; i < aProperties.length; i += 1 ){
		// Get the 'current' property
		oProperty = aProperties[ i ];
 
		// Get a texture modifier for the property
		oTextureModifier = getTextureModifier( oProperty, true );
		// If we do not have a texture modifier and could not create one
		if( !oTextureModifier ){
			// Next!!
			continue;
		}
 
		// Toggle inversion of the texture color
		oTextureModifier.invert = !oTextureModifier.invert;
	}
 
// Finalize the function and invoke
})();