// // Copyright (C) Jedrik D. Eliasen // // File: rigidbody_pluginCmd.cpp #pragma once #include "stdio.h" #include #include #include #include #include #include #include "Sphere.h" #include "Vec3f.h" #include "math.h" //Create a maya command called 'sphere_sphere_angular_collision_reaction' that //will call the doIt function DeclareSimpleCommand( sphere_sphere_angular_collision_reaction, "Jedrik D. Eliasen", "7.0"); //this function is what Maya will process MStatus sphere_sphere_angular_collision_reaction::doIt( const MArgList& args ) { MStatus stat = MS::kSuccess; //set variables x,y,z to make array calls easier int x = 0; int y = 1; int z = 2; //set the paramater variables double radius1, radius2; MVector translationS1, translationS2; MVector impulseForceVectorS1, impulseForceVectorS2; MVector impulseForceLocationS1, impulseForceLocationS2; MVector constantForceVectorS1, constantForceVectorS2; MVector constantForceLocationS1, constantForceLocationS2; MVector currentOrientationAnglesS1, currentOrientationAnglesS2; MVector angularVelocityS1, angularVelocityS2; MVector torqueS1, torqueS2; double mass1, cofr1, numChildren1; double mass2, cofr2, numChildren2; char temp1[10],temp2[10],temp3[10], temp4[10]; unsigned index; double three = 3; //set the 1st sphere's position to translationS1 index = args.flagIndex( "t1", "translateS1") + 1; args.get(index, translationS1); //set the 1st sphere's radius to radius1 index = args.flagIndex( "r1", "radius1") + 1; args.get(index, radius1); //set the 1st sphere's impulse force to impulseForceVectorS1 index = args.flagIndex( "ifv1", "impulseForceVectorS1") + 1; args.get(index, impulseForceVectorS1); //set the 1st sphere's impulse location to impulseForceLocationS1 index = args.flagIndex( "ifl1", "impulseForceLocationS1") + 1; args.get(index, impulseForceLocationS1); //set the 1st sphere's constant force to constantForceVectorS1 index = args.flagIndex( "cfv1", "constantForceVectorS1") + 1; args.get(index, constantForceVectorS1); //set the 1st sphere's constant location to constantForceLocationS1 index = args.flagIndex( "cfl1", "constantForceLocationS1") + 1; args.get(index, constantForceLocationS1); //set the 1st sphere's currient orientation to currentOrientationAnglesS1 index = args.flagIndex( "coa1", "currentOrientationAnglesS1") + 1; args.get(index, currentOrientationAnglesS1); //set the 1st sphere's angular velocity to angularVelocityS1 index = args.flagIndex( "av1", "angularVelocityS1") + 1; args.get(index, angularVelocityS1); //set the 1st sphere's torque to torqueS1 index = args.flagIndex( "tq1", "torqueS1") + 1; args.get(index, torqueS1); //set the 1st sphere's cofficient of resitution to cofr1 index = args.flagIndex( "cofr1", "COFRS1") + 1; args.get(index, cofr1); //set the 1st sphere's mass to mass1 index = args.flagIndex( "m1", "MassS1") + 1; args.get(index, mass1); //set the 1st sphere's number of children to numChildren1 index = args.flagIndex( "nc1", "NumChildrenS1") + 1; args.get(index, numChildren1); //////////////////////////////////////////////////////////////////////////////// //set the 2nd sphere's position to translationS2 index = args.flagIndex( "t2", "translateS2") + 1; args.get(index, translationS2); //set the 2nd sphere's radius to radius2 index = args.flagIndex( "r2", "radius2") + 1; args.get(index, radius2); //set the 2nd sphere's impulse force to impulseForceVectorS2 index = args.flagIndex( "ifv2", "impulseForceVectorS2") + 1; args.get(index, impulseForceVectorS2); //set the 2nd sphere's impulse location to impulseForceLocationS2 index = args.flagIndex( "ifl2", "impulseForceLocationS2") + 1; args.get(index, impulseForceLocationS2); //set the 2nd sphere's constant force to constantForceVectorS2 index = args.flagIndex( "cfv2", "constantForceVectorS2") + 1; args.get(index, constantForceVectorS2); //set the 2nd sphere's constant location to constantForceLocationS2 index = args.flagIndex( "cfl2", "constantForceLocationS2") + 1; args.get(index, constantForceLocationS2); //set the 2nd sphere's currient orientation to currentOrientationAnglesS2 index = args.flagIndex( "coa2", "currentOrientationAnglesS2") + 1; args.get(index, currentOrientationAnglesS2); //set the 2nd sphere's angular velocity to angularVelocityS2 index = args.flagIndex( "av2", "angularVelocityS2") + 1; args.get(index, angularVelocityS2); //set the 2nd sphere's torque to torqueS2 index = args.flagIndex( "tq2", "torqueS2") + 1; args.get(index, torqueS2); //set the 2nd sphere's cofficient of resitution to cofr2 index = args.flagIndex( "cofr2", "COFRS2") + 1; args.get(index, cofr2); //set the 2nd sphere's mass to mass2 index = args.flagIndex( "m2", "MassS2") + 1; args.get(index, mass2); //set the 2nd sphere's number of children to numChildren2 index = args.flagIndex( "nc2", "NumChildrenS2") + 1; args.get(index, numChildren2); //set the centers of the spheres to two vectors Vec3f vec1(translationS1[x],translationS1[y],translationS1[z]); Vec3f vec2(translationS2[x],translationS2[y],translationS2[z]); Vec3f pointXn(0,0,0); bool is_intersection = false; Sphere s1; Sphere s2; //Set Sphere 1 Data Attributes s1.Radius = radius1; s1.COM_Position.x = translationS1[x]; s1.COM_Position.y = translationS1[y]; s1.COM_Position.z = translationS1[z]; s1.Mass = mass1; s1.ImpulseForce.ForceVector.x = impulseForceVectorS1[x]; s1.ImpulseForce.ForceVector.y = impulseForceVectorS1[y]; s1.ImpulseForce.ForceVector.z = impulseForceVectorS1[z]; s1.ImpulseForce.ForceLocation.x = constantForceLocationS1[x]; s1.ImpulseForce.ForceLocation.y = constantForceLocationS1[y]; s1.ImpulseForce.ForceLocation.z = constantForceLocationS1[z]; s1.ConstantForce.ForceVector.x = constantForceVectorS1[x]; s1.ConstantForce.ForceVector.y = constantForceVectorS1[y]; s1.ConstantForce.ForceVector.z = constantForceVectorS1[z]; s1.ConstantForce.ForceLocation.x = constantForceLocationS1[x]; s1.ConstantForce.ForceLocation.y = constantForceLocationS1[y]; s1.ConstantForce.ForceLocation.z = constantForceLocationS1[z]; s1.CurrentOrientationAngles.x = currentOrientationAnglesS1[x]; s1.CurrentOrientationAngles.y = currentOrientationAnglesS1[y]; s1.CurrentOrientationAngles.z = currentOrientationAnglesS1[z]; s1.AngularVelocity.x = angularVelocityS1[x]; s1.AngularVelocity.y = angularVelocityS1[y]; s1.AngularVelocity.z = angularVelocityS1[z]; s1.Torque.x = 0.0f; s1.Torque.y = 0.0f; s1.Torque.z = 0.0f; s1.COFR = cofr1; s1.numChildren = numChildren1; //Set Sphere 2 Data Attributes s2.Radius = radius2; s2.COM_Position.x = translationS2[x]; s2.COM_Position.y = translationS2[y]; s2.COM_Position.z = translationS1[z]; s1.Mass = mass1; s1.ImpulseForce.ForceVector.x = impulseForceVectorS2[x]; s2.ImpulseForce.ForceVector.y = impulseForceVectorS2[y]; s2.ImpulseForce.ForceVector.z = impulseForceVectorS2[z]; s2.ImpulseForce.ForceLocation.x = constantForceLocationS2[x]; s2.ImpulseForce.ForceLocation.y = constantForceLocationS2[y]; s2.ImpulseForce.ForceLocation.z = constantForceLocationS2[z]; s2.ConstantForce.ForceVector.x = constantForceVectorS2[x]; s2.ConstantForce.ForceVector.y = constantForceVectorS2[y]; s2.ConstantForce.ForceVector.z = constantForceVectorS2[z]; s2.ConstantForce.ForceLocation.x = constantForceLocationS2[x]; s2.ConstantForce.ForceLocation.y = constantForceLocationS2[y]; s2.ConstantForce.ForceLocation.z = constantForceLocationS2[z]; s2.CurrentOrientationAngles.x = currentOrientationAnglesS2[x]; s2.CurrentOrientationAngles.y = currentOrientationAnglesS2[y]; s2.CurrentOrientationAngles.z = currentOrientationAnglesS2[z]; s2.AngularVelocity.x = angularVelocityS2[x]; s2.AngularVelocity.y = angularVelocityS2[y]; s2.AngularVelocity.z = angularVelocityS2[z]; s2.Torque.x = 0.0f; s2.Torque.y = 0.0f; s2.Torque.z = 0.0f; s2.COFR = cofr2; s2.numChildren = numChildren2; //////////////////////////////////////////////////////////////////////////////// //Calculate Angular Contribution //Calc Numerator Vec3f Veloc = s1.AngularVelocity - s2.AngularVelocity; Veloc.negate(); float AveE = (s1.COFR + s2.COFR) / 2.0; Vec3f Numerator = Veloc*(AveE + 1.0f); //Calc Denomenator Vec3f Norm = s1.COM_Position - s2.COM_Position; Norm.normalize(); //Find Location where the Force acts of Object 2 Vec3f FLocation2 = Norm*s2.Radius; Vec3f temp = FLocation2.cross(Norm); //Divide by Rotational Inertia temp.x = temp.x/s2.RotationalInertia.x; temp.x = temp.y/s2.RotationalInertia.y; temp.x = temp.z/s2.RotationalInertia.z; temp = temp.cross(FLocation2); //dot with normal float First = Norm.dot(temp); //Find where the force acts on sphere 1 Norm.negate(); Vec3f FLocation1 = Norm*s1.Radius; temp = FLocation1.cross(Norm); //Divide by Rotational Inertia temp.x = temp.x/s1.RotationalInertia.x; temp.x = temp.y/s1.RotationalInertia.y; temp.x = temp.z/s1.RotationalInertia.z; temp = temp.cross(FLocation1); float Second = Norm.dot(temp); float Denomenator = 1.0f/s1.Mass + 1.0f/s2.Mass + First + Second; Vec3f ForceVector; Vec3f ForceLocation; ForceVector = Numerator/Denomenator; ForceLocation = FLocation1; s1.ImpulseForce.ForceVector = ForceVector; s1.ImpulseForce.ForceLocation = ForceLocation; //////////////////////////////////////////////////////////////////////////////// //cannot pass back a vector //create an array of double that will pass back the 2 vectors, //LinearVelocity1 & 2 as doubles double result[6]; result[0] = ForceVector.x; result[1] = ForceVector.y; result[2] = ForceVector.z; result[3] = ForceLocation.x; result[4] = ForceLocation.y; result[5] = ForceLocation.z; //convert the C++ double array to a Maya API double array MDoubleArray return_array(result, 5); //'return' the result to MEL clearResult(); setResult( return_array ); //this will return to MEL a true or false depending on whether the function //was successful or not return stat; }