// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // // // // Creation Date: 2003 // // // // // // createMotionFieldExpression // // // None. // // // This command creates a force that pushes a fluid based on the motion // of an object. This is an old form of createMotionField from before // inheritVelocity was added to drag fields. This uses an expression to // adjust a directional field such that it pushes in the direction of // motion. The newer command createMotionField is generally preferable // because rotational and scale motions are additionally handled. // To use createMotionFieldExpression one selects the objects // that one wishes to push the fluid // with and the fluids to affect. At least one fluid and one // non-fluid must be selected. One will not see an effect until the object // is animated. MakeFluidPusher creates a force for each object and sizes the // volume boundary of the force to be a bit larger than the object. An // expression is generated that sets the direction and magnitude of the // force based on the current motion of the object. The attribute // "pushIntensity" is added to the force node under extra attributes. // This allows one to adjust the magnitude of the push force. // Note that if one also does a fluid->makeCollide on the object that the // pushIntensity may need to be increased, as the force evaluates to zero // in the colliding regions of the fluid. This is one reason why // the force bounds to be larger than the object size. // Adjusting the scale and volume shape of the force can help to achieve // the best effect. // // // None. // // // // Create a fluid with emitter // Create2DContainerEmitter; // // Create an animated sphere // sphere; // move -r 3 3 0; // setKeyframe; // currentTime 100; // move -r -6 -6 0; // setKeyframe; // select -r fluidShape1 nurbsSphere1; // createMotionField; // global proc createMotionFieldExpression() { float $pushIntensity = 10.0; float $flOverScale = 1.6/2.0; float $maxAspect = 0.1; string $fluids[] = `ls -sl -dag -type fluidShape`; string $selObjs[] = `ls -sl -type transform`; string $objs[]; int $numObjs=0; int $i; for( $i = 0; $i < size($selObjs); $i++ ){ string $fls[] = `ls -dag -type fluidShape $selObjs[$i]`; if( 0 == size( $fls )){ $objs[$numObjs] = $selObjs[$i]; $numObjs++; } } if( $numObjs == 0 || size($fluids) == 0 ){ warning ((uiRes("m_createMotionFieldExpression.kNeedFluid"))); return; } string $fields[]; int $numFields =0; for( $i = 0; $i < $numObjs; $i++ ){ select -r $fluids; Uniform; $selObjs = `ls -sl`; string $field = $selObjs[0]; $field = `rename $field "motionField#"`; $fields[ $numFields ] = $field; $numFields++; setAttr ($field + ".attenuation") .1; setAttr ($field + ".volumeShape") 2; string $obj = $objs[$i]; float $bbox[] = `exactWorldBoundingBox $obj`; $min[0] = $bbox[0]; $min[1] = $bbox[1]; $min[2] = $bbox[2]; $max[0] = $bbox[3]; $max[1] = $bbox[4]; $max[2] = $bbox[5]; float $fsx =$flOverScale *( $max[0] - $min[0] ); float $fsy =$flOverScale *( $max[1] - $min[1] ); float $fsz =$flOverScale *( $max[2] - $min[2] ); float $maxScale = $fsx; if( $maxScale < $fsy ){ $maxScale = $fsy; } if( $maxScale < $fsz ){ $maxScale = $fsz; } $maxScale *= $maxAspect; // avoid flat forces if( $fsx < $maxScale ) { $fsx = $maxScale; } if( $fsy < $maxScale ){ $fsy = $maxScale; } if( $fsz < $maxScale ){ $fsz = $maxScale; } setAttr ($field + ".tx") ($min[0] + 0.5 * ($max[0]-$min[0])); setAttr ($field + ".ty") ($min[1] + 0.5 * ($max[1]-$min[1])); setAttr ($field + ".tz") ($min[2] + 0.5 * ($max[2]-$min[2])); setAttr ($field + ".sx") $fsx; setAttr ($field + ".sy") $fsy; setAttr ($field + ".sz") $fsz; parent $field $obj; addAttr -ln pushIntensity -sn pi -at double -min -0 -max 100 -dv $pushIntensity $field; setAttr -e -keyable true ($field + ".pushIntensity"); string $exp = ( "float $x = "+$obj+".translateX;\n" +"float $y = "+$obj+".translateY;\n" +"float $z = "+$obj+".translateZ;\n" +"float $to[3] = `getAttr -time (frame - 1.5) " + $obj + ".translate`;\n" +"$x -= $to[0];\n" +"$y -= $to[1];\n" +"$z -= $to[2];\n" +"float $len = sqrt( $x*$x + $y*$y + $z*$z );\n" +"if( $len > 0.00001 ){\n" +" $x /= $len;\n" +" $y /= $len;\n" +" $z /= $len;\n" +"}\n" + $field + ".directionX = $x;\n" + $field + ".directionY = $y;\n" + $field + ".directionZ = $z;\n" + $field + ".magnitude = "+$field+".pushIntensity * $len*20;\n" ); expression -s $exp; } select -r $fields; }