void exportTerrain::printTransformData(const MFnLight& theLight) { MStatus status; unsigned numParents = theLight.parentCount(&status); MObject transformNode; //will only use the first parent if(numParents != 0){ transformNode = theLight.parent(0,&status); // This node has no transform - i.e., it's the world node } else return; if (!status && status.statusCode () == MStatus::kInvalidParameter) return; MFnTransform transform(transformNode, &status); if (!status) { status.perror("MFnTransform constructor"); return; } fout << "Name: " << transform.name(&status) << endl; fout << "Transform: " << transform.translation( MSpace::kTransform,&status) << endl; MQuaternion rot; status = transform.getRotation(rot); double rotD[4]; rot.get(rotD); MColor tempRot(rotD[0],rotD[1],rotD[2],rotD[3]); // fout << "Rotation: " << tempRot << endl; printLightData(theLight); }
// Load the textures, update the necessary variable values, initialize register combiners, // save and load the matrices with the proper values // MStatus hwRefractReflectShader_NV20::preDraw(const MDrawRequest& request, M3dView& view) { MStatus stat = loadTextures( request, view); if( MS::kSuccess != stat ) return stat; // get the reflectivity value // MPlug tPlug(thisMObject(), reflectivity); if( tPlug.getValue( fReflectivity ) ) { if( fReflectivity < 0.01f ) fReflectivity = 0.01f; if( fReflectivity > 1.0f ) fReflectivity = 1.0f; } else fReflectivity = 0.5f; // get the refraction index value // MPlug rPlug(thisMObject(), refractionIndex); if( rPlug.getValue( fRefractionIndex ) ) { if ( fRefractionIndex < 1.0f ) fRefractionIndex = 1.0f; if ( fRefractionIndex > 2.0f ) fRefractionIndex = 2.0f; } else fRefractionIndex = 1.0f; initCombiners( request, view ); // Compute the camera rotation angle and axis // MDagPath cameraPath; MStatus status = view.getCamera( cameraPath ); MMatrix mmatrix = cameraPath.inclusiveMatrix( &status ); MTransformationMatrix tmatrix( mmatrix ); MQuaternion camRotation = tmatrix.rotation(); MVector camAxis; double camTheta; camRotation.getAxisAngle( camAxis, camTheta ); // Convert to degrees from radians camTheta *= 57.295779513082320876798154814105; // == (180 / M_PI) view.beginGL(); glMatrixMode( GL_TEXTURE ); glPushMatrix(); glLoadIdentity(); glScalef(1.0, -1.0, 1.0); glRotated( camTheta, camAxis[0], camAxis[1], camAxis[2]); glMatrixMode( GL_MODELVIEW ); view.endGL(); return stat; }
void MannequinMoveManipulator::glDrawCone(GLUquadricObj* quadric, MPoint pos, MVector dir, float height, float radius) const { MQuaternion zToDir = MVector::zAxis.rotateTo(dir); MVector axis; double rotateRad; zToDir.getAxisAngle(axis, rotateRad); double rotateDeg = MAngle(rotateRad).as(MAngle::kDegrees); glPushMatrix(); glTranslated(pos.x, pos.y, pos.z); glRotated(rotateDeg, axis.x, axis.y, axis.z); gluCylinder(quadric, radius, 0.0, height, 8, 1); glPopMatrix(); }
void n_tentacle::bipolarityCheck(MQuaternion &quat1, MQuaternion &quat2) { // the quaternion's imaginary part can describe two rotations at the same time, // we make sure we always orient the two quaternions to the same direction double dot = (quat1.w * quat2.w) + (quat1.x * quat2.x) + (quat1.y * quat2.y) + (quat1.z * quat2.z); if(dot < 0.0) { quat1.negateIt(); } }
// create constraint void MBulletContext::createConstraint(unsigned int * constraintId, unsigned int parentObjectId, unsigned int objectId, const MVector3 & pivot, bool disableParentCollision) { btRigidBody * bA = btRigidBody::upcast(m_collisionObjects[parentObjectId]); btRigidBody * bB = btRigidBody::upcast(m_collisionObjects[objectId]); if(bA && bB) { bA->setActivationState(DISABLE_DEACTIVATION); bB->setActivationState(DISABLE_DEACTIVATION); *constraintId = m_constraints.size(); MVector3 position, euler; MQuaternion rotation; MMatrix4x4 matrix, matrix1, matrix2, rotMatrix; rotMatrix.setRotationEuler(90, 0, 0); getObjectTransform(parentObjectId, &position, &rotation); matrix1.setRotationAxis(rotation.getAngle(), rotation.getAxis()); matrix1.setTranslationPart(position); getObjectTransform(objectId, &position, &rotation); matrix2.setRotationAxis(rotation.getAngle(), rotation.getAxis()); matrix2.setTranslationPart(position + matrix2.getRotatedVector3(pivot)); matrix = (matrix1.getInverse() * matrix2) * rotMatrix; euler = matrix.getEulerAngles(); position = matrix.getTranslationPart(); rotation.setFromAngles(euler.x, euler.y, euler.z); btTransform frameInA, frameInB; frameInA = btTransform::getIdentity(); frameInA.setOrigin(btVector3(position.x, position.y, position.z)); frameInA.setRotation(btQuaternion(rotation.values[0], rotation.values[1], rotation.values[2], rotation.values[3])); rotation.setFromAngles(90, 0, 0); frameInB = btTransform::getIdentity(); frameInB.setOrigin(btVector3(pivot.x, pivot.y, pivot.z)); frameInB.setRotation(btQuaternion(rotation.values[0], rotation.values[1], rotation.values[2], rotation.values[3])); btGeneric6DofSpringConstraint * constraint = new btGeneric6DofSpringConstraint( *bA, *bB, frameInA, frameInB, true ); m_constraints.push_back(constraint); m_dynamicsWorld->addConstraint(constraint, disableParentCollision); } }
void n_tentacle::computeSlerp(const MMatrix &matrix1, const MMatrix &matrix2, const MFnNurbsCurve &curve, double parameter, double blendRot, double iniLength, double curveLength, double stretch, double globalScale, int tangentAxis, MVector &outPos, MVector &outRot) { //curveLength = curve.length() double lenRatio = iniLength / curveLength; MQuaternion quat1; quat1 = matrix1; MQuaternion quat2; quat2 = matrix2; this->bipolarityCheck(quat1, quat2); //need to adjust the parameter in order to maintain the length between elements, also for the stretch MVector tangent; MPoint pointAtParam; MPoint finaPos; double p = lenRatio * parameter * globalScale; double finalParam = p + (parameter - p) * stretch; if(curveLength * finalParam > curveLength) { double lengthDiff = curveLength - (iniLength * parameter); double param = curve.knot(curve.numKnots() - 1); tangent = curve.tangent(param, MSpace::kWorld); tangent.normalize(); curve.getPointAtParam(param, pointAtParam, MSpace::kWorld); finaPos = pointAtParam; pointAtParam += (- tangent) * lengthDiff; //MGlobal::displayInfo("sdf"); } else { double param = curve.findParamFromLength(curveLength * finalParam); tangent = curve.tangent(param, MSpace::kWorld); tangent.normalize(); curve.getPointAtParam(param, pointAtParam, MSpace::kWorld); } MQuaternion slerpQuat = slerp(quat1, quat2, blendRot); MMatrix slerpMatrix = slerpQuat.asMatrix(); int axisId = abs(tangentAxis) - 1; MVector slerpMatrixYAxis = MVector(slerpMatrix(axisId, 0), slerpMatrix(axisId, 1), slerpMatrix(axisId, 2)); slerpMatrixYAxis.normalize(); if(tangentAxis < 0) slerpMatrixYAxis = - slerpMatrixYAxis; double angle = tangent.angle(slerpMatrixYAxis); MVector axis = slerpMatrixYAxis ^ tangent; axis.normalize(); MQuaternion rotationToSnapOnCurve(angle, axis); MQuaternion finalQuat = slerpQuat * rotationToSnapOnCurve; MEulerRotation finalEuler = finalQuat.asEulerRotation(); outRot.x = finalEuler.x; outRot.y = finalEuler.y; outRot.z = finalEuler.z; outPos = pointAtParam; }
void rigidBodyNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data) { if (!m_rigid_body) return; // std::cout << "rigidBodyNode::computeWorldMatrix" << std::endl; MObject thisObject(thisMObject()); MFnDagNode fnDagNode(thisObject); MObject update; MPlug(thisObject, ca_rigidBody).getValue(update); MPlug(thisObject, ca_rigidBodyParam).getValue(update); vec3f pos; quatf rot; MStatus status; MFnTransform fnParentTransform(fnDagNode.parent(0, &status)); double mscale[3]; fnParentTransform.getScale(mscale); m_rigid_body->get_transform(pos, rot); if(dSolverNode::isStartTime) { // allow to edit ptranslation and rotation MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status); MQuaternion mrotation; fnParentTransform.getRotation(mrotation, MSpace::kTransform); float deltaPX = (float)mtranslation.x - pos[0]; float deltaPY = (float)mtranslation.y - pos[1]; float deltaPZ = (float)mtranslation.z - pos[2]; float deltaRX = (float)mrotation.x - rot[1]; float deltaRY = (float)mrotation.y - rot[2]; float deltaRZ = (float)mrotation.z - rot[3]; float deltaRW = (float)mrotation.w - rot[0]; float deltaSq = deltaPX * deltaPX + deltaPY * deltaPY + deltaPZ * deltaPZ + deltaRX * deltaRX + deltaRY * deltaRY + deltaRZ * deltaRZ + deltaRW * deltaRW; if(deltaSq > FLT_EPSILON) { m_rigid_body->set_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->set_interpolation_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->update_constraint(); MDataHandle hInitPos = data.outputValue(ia_initialPosition); float3 &ihpos = hInitPos.asFloat3(); ihpos[0] = (float)mtranslation.x; ihpos[1] = (float)mtranslation.y; ihpos[2] = (float)mtranslation.z; MDataHandle hInitRot = data.outputValue(ia_initialRotation); float3 &ihrot = hInitRot.asFloat3(); MEulerRotation newrot(mrotation.asEulerRotation()); ihrot[0] = rad2deg((float)newrot.x); ihrot[1] = rad2deg((float)newrot.y); ihrot[2] = rad2deg((float)newrot.z); } } else { // if not start time, lock position and rotation for active rigid bodies float mass = 0.f; MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass); if(mass > 0.f) { fnParentTransform.setTranslation(MVector(pos[0], pos[1], pos[2]), MSpace::kTransform); fnParentTransform.setRotation(MQuaternion(rot[1], rot[2], rot[3], rot[0])); } } float mass = 0.f; MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass); float curMass = m_rigid_body->get_mass(); bool changedMassStatus= false; if ((curMass > 0.f) != (mass > 0.f)) { changedMassStatus = true; } if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); m_rigid_body->set_mass(mass); m_rigid_body->set_inertia((float)mass * m_rigid_body->collision_shape()->local_inertia()); if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); float restitution = 0.f; MPlug(thisObject, rigidBodyNode::ia_restitution).getValue(restitution); m_rigid_body->set_restitution(restitution); float friction = 0.5f; MPlug(thisObject, rigidBodyNode::ia_friction).getValue(friction); m_rigid_body->set_friction(friction); float linDamp = 0.f; MPlug(thisObject, rigidBodyNode::ia_linearDamping).getValue(linDamp); m_rigid_body->set_linear_damping(linDamp); float angDamp = 0.f; MPlug(thisObject, rigidBodyNode::ia_angularDamping).getValue(angDamp); m_rigid_body->set_angular_damping(angDamp); data.setClean(plug); //set the scale to the collision shape m_rigid_body->collision_shape()->set_scale(vec3f((float)mscale[0], (float)mscale[1], (float)mscale[2])); }
bool xmlArmatureAnimLoad(const char * filename, void * data) { TiXmlDocument doc(filename); if(! doc.LoadFile()) return false; TiXmlHandle hDoc(&doc); TiXmlElement * pRootNode; TiXmlHandle hRoot(0); // Maratis pRootNode = hDoc.FirstChildElement().Element(); if(! pRootNode) return false; if(strcmp(pRootNode->Value(), "Maratis") != 0) return false; hRoot = TiXmlHandle(pRootNode); // BonesAnim TiXmlElement * armatureAnimNode = pRootNode->FirstChildElement("ArmatureAnim"); if(! armatureAnimNode) return false; unsigned int bonesAnimNumber = 0; armatureAnimNode->QueryUIntAttribute("num", &bonesAnimNumber); if(bonesAnimNumber == 0) return false; // create armature anim MArmatureAnim * armatureAnim = (MArmatureAnim *)data; MObject3dAnim * objAnims = armatureAnim->allocBonesAnim(bonesAnimNumber); // Bone TiXmlElement * boneNode = armatureAnimNode->FirstChildElement("Bone"); for(boneNode; boneNode; boneNode=boneNode->NextSiblingElement("Bone")) { // position TiXmlElement * positionNode = boneNode->FirstChildElement("position"); if(positionNode) { unsigned int kSize = 0; positionNode->QueryUIntAttribute("num", &kSize); MKey * keys = objAnims->allocPositionKeys(kSize); readVector3Keys(positionNode, keys); } // rotation TiXmlElement * rotationNode = boneNode->FirstChildElement("rotation"); if(rotationNode) { unsigned int kSize = 0; rotationNode->QueryUIntAttribute("num", &kSize); MKey * keys = objAnims->allocRotationKeys(kSize); // k TiXmlElement * kNode = rotationNode->FirstChildElement("k"); for(kNode; kNode; kNode=kNode->NextSiblingElement("k")) { int t = 0; MVector3 euler; MQuaternion * rotation = keys->createQuaternionData(); kNode->QueryIntAttribute("t", &t); kNode->QueryFloatAttribute("x", &euler.x); kNode->QueryFloatAttribute("y", &euler.y); kNode->QueryFloatAttribute("z", &euler.z); rotation->setFromAngles(euler.x, euler.y, euler.z); keys->setT(t); keys++; } } // scale TiXmlElement * scaleNode = boneNode->FirstChildElement("scale"); if(scaleNode) { unsigned int kSize = 0; scaleNode->QueryUIntAttribute("num", &kSize); MKey * keys = objAnims->allocScaleKeys(kSize); readVector3Keys(scaleNode, keys); } objAnims++; } return true; }
MStatus HRBFSkinCluster::skinDQ(MMatrixArray& transforms, int numTransforms, MArrayDataHandle& weightListHandle, MItGeometry& iter) { MStatus returnStatus; // compute dual quaternions. we're storing them as a parallel array. std::vector<MQuaternion> tQuaternions(numTransforms); // translation quaterions std::vector<MQuaternion> rQuaternions(numTransforms); // rotation quaternions for (int i = 0; i < numTransforms; i++) { rQuaternions.at(i) = getRotationQuaternion(transforms[i]); rQuaternions.at(i).normalizeIt(); tQuaternions.at(i) = getTranslationQuaternion(transforms[i], rQuaternions.at(i)); #if DEBUG_PRINTS std::cout << "rota quaternion " << i << " is: " << rQuaternions.at(i) << std::endl; std::cout << "tran quaternion " << i << " is: " << tQuaternions.at(i) << std::endl; #endif } MQuaternion rBlend; // blended rotation quaternions MQuaternion tBlend; // blended translation quaternions MQuaternion scaleMe; // Maya's quaternion scaling is in-place double weight; // Iterate through each point in the geometry. // for (; !iter.isDone(); iter.next()) { MPoint pt = iter.position(); MPoint skinned; rBlend = MQuaternion(); // reset tBlend = MQuaternion(); // reset rBlend[3] = 0.0; tBlend[3] = 0.0; // get the weights for this point MArrayDataHandle weightsHandle = weightListHandle.inputValue().child(weights); // compute the skinning for (int i = 0; i<numTransforms; ++i) { if (MS::kSuccess == weightsHandle.jumpToElement(i)) { weight = weightsHandle.inputValue().asDouble(); scaleMe = rQuaternions.at(i); rBlend = rBlend + scaleMe.scaleIt(weight); scaleMe = tQuaternions.at(i); tBlend = tBlend + scaleMe.scaleIt(weight); } } MMatrix dqMatrix = makeDQMatrix(rBlend.normalizeIt(), tBlend); skinned = pt * dqMatrix; // Set the final position. iter.setPosition(skinned); // advance the weight list handle weightListHandle.next(); } return returnStatus; }
void curveColliderLocator::draw(M3dView &view, const MDagPath &path, M3dView::DisplayStyle style, M3dView::DisplayStatus status) { // // Get the input curve // MObject thisNode = thisMObject(); MPlug radiusPlug(thisNode, colliderRadiusIn); MPlug colorPlugR(thisNode, colliderColorR); MPlug colorPlugG(thisNode, colliderColorG); MPlug colorPlugB(thisNode, colliderColorB); MPlug colorPlugT(thisNode, colliderTransparency); MPlug radiusElement; double radius; double radius2; double param; double param2; double paramNorm; radiusPlug.getValue(radius); MStatus stat; MQuaternion rotateQuat; double degreesToRadians = ( M_PI/ 180.0 ); double radiansToDegrees = ( 180.0/M_PI ); double rotateRadians; MVector crvNormalRotated; MPointArray radiusPts; MPoint radiusPt; // Alternate method of getting the MFnNurbsCurve: MPlug curvePlug(thisNode, colliderCurveIn); MPlugArray inputCrvArray; curvePlug.connectedTo(inputCrvArray, true, false); MObject crvColliderObj = inputCrvArray[0].node(); MFnNurbsCurve cColliderFn(crvColliderObj, &stat); if(!stat){ MGlobal::displayInfo(MString("Error creating MFnNurbsCurve for collider curve")); return; } MFnDagNode crvDagNode(crvColliderObj); MDagPath crvDagPath; crvDagNode.getPath(crvDagPath); MMatrix crvXform = crvDagPath.inclusiveMatrix(); int numSpans = cColliderFn.numSpans(); MPoint crvPoint; MPoint crvPoint2; GLUquadricObj* qobj = gluNewQuadric(); view.beginGL(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DRAW SMOOTH SHADED ///////////////////////////////////////////////////////////////////////////////////////////////////////////// if ( ( style == M3dView::kFlatShaded ) || ( style == M3dView::kGouraudShaded ) ) { glPushAttrib( GL_ALL_ATTRIB_BITS ); glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); glEnable(GL_BLEND); glEnable(GL_LIGHT0); glMatrixMode( GL_MODELVIEW ); float3 color; colorPlugR.getValue(color[0]); colorPlugG.getValue(color[1]); colorPlugB.getValue(color[2]); float transparency; colorPlugT.getValue(transparency); float diffuse[] = {color[0], color[1], color[2], transparency}; float specular[] = { 0.7f, 0.7f, 0.7f, transparency}; float shine[] = { 100.0f }; float ambient[] = { 0.2f, 0.2f, 0.2f, transparency }; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shine); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); // Draw the beginning and ending sphere caps glPushMatrix(); cColliderFn.getPointAtParam(0, crvPoint, MSpace::kWorld); crvPoint = crvPoint*crvXform; glTranslatef(crvPoint.x, crvPoint.y, crvPoint.z); radiusElement = radiusPlug.elementByPhysicalIndex(0, &stat); radiusElement.getValue(radius); gluSphere(qobj, radius, 16, 16); glPopMatrix(); glPushMatrix(); cColliderFn.getPointAtParam(numSpans, crvPoint, MSpace::kWorld); crvPoint = crvPoint*crvXform; glTranslatef(crvPoint.x, crvPoint.y, crvPoint.z); radiusElement = radiusPlug.elementByPhysicalIndex( (radiusPlug.numElements() - 1), &stat); radiusElement.getValue(radius); gluSphere(qobj, radius, 16, 16); glPopMatrix(); int numStacks = numSpans*30; int numSlices = 32; // Initialize our point array with the radius values radiusPts.clear(); radiusPts.setLength(radiusPlug.numElements()); for(int radiusItr = 0; radiusItr < radiusPlug.numElements(); radiusItr++){ radiusElement = radiusPlug.elementByPhysicalIndex(radiusItr, &stat); if(!stat){MGlobal::displayError(MString("Could not get radius element.")); return;} radiusElement.getValue(radius); radiusPt.x = (double)radius; radiusPt.y = 0.0; radiusPt.z = 0.0; radiusPts[radiusItr] = radiusPt; } if(numStacks>1){ for(uint crvItr = 0; crvItr < numStacks - 1; crvItr++){ param = (float(crvItr)/float(numStacks-1))*numSpans; param2 = (float(crvItr+1)/float(numStacks-1))*numSpans; cColliderFn.getPointAtParam(param, crvPoint, MSpace::kWorld); crvPoint = crvPoint*crvXform; cColliderFn.getPointAtParam(param2, crvPoint2, MSpace::kWorld); crvPoint2 = crvPoint2 * crvXform; // Determine the radius value int lastRadiusIndex = radiusPlug.numElements() - 1; if(lastRadiusIndex == 0){ radiusElement = radiusPlug.elementByPhysicalIndex(0, &stat); if(!stat){MGlobal::displayError(MString("Could not get radius element.")); return;} radiusElement.getValue(radius); radius2 = radius; }else if(lastRadiusIndex > 0){ paramNorm = param/numSpans; radiusPt = getInterpolatedSplinePoint(paramNorm, radiusPts); radius = radiusPt.x; paramNorm = param2/numSpans; radiusPt = getInterpolatedSplinePoint(paramNorm, radiusPts); radius2 = radiusPt.x; } // First, we need to determine our starting position by travelling along the normal MVector crvNormal = cColliderFn.normal(param, MSpace::kWorld); crvNormal = crvNormal * crvXform; MVector crvTangent = cColliderFn.tangent(param, MSpace::kWorld); crvTangent = crvTangent * crvXform; crvNormal.normalize(); crvTangent.normalize(); MVector crvNormal2 = cColliderFn.normal(param2, MSpace::kWorld); crvNormal2 = crvNormal2 * crvXform; MVector crvTangent2 = cColliderFn.tangent(param2, MSpace::kWorld); crvTangent2 = crvTangent2 * crvXform; crvNormal2.normalize(); crvTangent2.normalize(); // glTranslatef(crvNormal.x, crvNormal.y, crvNormal.z); glBegin(GL_QUADS); for(int sliceItr = 0; sliceItr < numSlices; sliceItr++){ // quad vertex 4 rotateRadians = ((((float)sliceItr+1)/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint.x + (crvNormalRotated.x*radius), (float)crvPoint.y + (crvNormalRotated.y*radius), (float)crvPoint.z + (crvNormalRotated.z*radius)); // quad vertex 3 rotateRadians = ((((float)sliceItr+1)/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent2, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint2.x + (crvNormalRotated.x*radius2), (float)crvPoint2.y + (crvNormalRotated.y*radius2), (float)crvPoint2.z + (crvNormalRotated.z*radius2)); // quad vertex 2 rotateRadians = (((float)sliceItr/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent2, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint2.x + (crvNormalRotated.x*radius2), (float)crvPoint2.y + (crvNormalRotated.y*radius2), (float)crvPoint2.z + (crvNormalRotated.z*radius2)); // quad vertex 1 rotateRadians = (((float)sliceItr/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint.x + (crvNormalRotated.x*radius), (float)crvPoint.y + (crvNormalRotated.y*radius), (float)crvPoint.z + (crvNormalRotated.z*radius)); } glEnd(); } } glPopAttrib(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // END SMOOTH SHADED ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DRAW WIREFRAME ///////////////////////////////////////////////////////////////////////////////////////////////////////////// if ( style == M3dView::kWireFrame || status == M3dView::kActive || status == M3dView::kLead) { glPushAttrib( GL_ALL_ATTRIB_BITS ); // Draw the beginning and ending sphere caps // Quadrilateral strips glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); glPushMatrix(); cColliderFn.getPointAtParam(0, crvPoint, MSpace::kWorld); crvPoint = crvPoint*crvXform; glTranslatef(crvPoint.x, crvPoint.y, crvPoint.z); radiusElement = radiusPlug.elementByPhysicalIndex(0, &stat); radiusElement.getValue(radius); gluSphere(qobj, radius, 16, 16); glPopMatrix(); glPushMatrix(); cColliderFn.getPointAtParam(numSpans, crvPoint, MSpace::kWorld); crvPoint = crvPoint*crvXform; glTranslatef(crvPoint.x, crvPoint.y, crvPoint.z); radiusElement = radiusPlug.elementByPhysicalIndex( (radiusPlug.numElements() - 1), &stat); radiusElement.getValue(radius); gluSphere(qobj, radius, 16, 16); glPopMatrix(); int numStacks = numSpans*10; int numSlices = 32; // Initialize our point array with the radius values radiusPts.clear(); radiusPts.setLength(radiusPlug.numElements()); for(int radiusItr = 0; radiusItr < radiusPlug.numElements(); radiusItr++){ radiusElement = radiusPlug.elementByPhysicalIndex(radiusItr, &stat); if(!stat){MGlobal::displayError(MString("Could not get radius element.")); return;} radiusElement.getValue(radius); radiusPt.x = (double)radius; radiusPt.y = 0.0; radiusPt.z = 0.0; radiusPts[radiusItr] = radiusPt; } for(uint crvItr = 0; crvItr < numStacks; crvItr++){ param = (float(crvItr)/float(numStacks))*numSpans; param2 = (float(crvItr+1)/float(numStacks))*numSpans; cColliderFn.getPointAtParam(param, crvPoint, MSpace::kWorld); crvPoint = crvPoint*crvXform; cColliderFn.getPointAtParam(param2, crvPoint2, MSpace::kWorld); crvPoint2 = crvPoint2 * crvXform; // Determine the radius value int lastRadiusIndex = radiusPlug.numElements() - 1; if(lastRadiusIndex == 0){ radiusElement = radiusPlug.elementByPhysicalIndex(0, &stat); if(!stat){MGlobal::displayError(MString("Could not get radius element.")); return;} radiusElement.getValue(radius); radius2 = radius; }else if(lastRadiusIndex > 0){ paramNorm = param/numSpans; radiusPt = getInterpolatedSplinePoint(paramNorm, radiusPts); radius = radiusPt.x; paramNorm = param2/numSpans; radiusPt = getInterpolatedSplinePoint(paramNorm, radiusPts); radius2 = radiusPt.x; } // First, we need to determine our starting position by travelling along the normal MVector crvNormal = cColliderFn.normal(param, MSpace::kWorld); crvNormal = crvNormal * crvXform; MVector crvTangent = cColliderFn.tangent(param, MSpace::kWorld); crvTangent = crvTangent * crvXform; crvNormal.normalize(); crvTangent.normalize(); MVector crvNormal2 = cColliderFn.normal(param2, MSpace::kWorld); crvNormal2 = crvNormal2 * crvXform; MVector crvTangent2 = cColliderFn.tangent(param2, MSpace::kWorld); crvTangent2 = crvTangent2 * crvXform; crvNormal2.normalize(); crvTangent2.normalize(); // glTranslatef(crvNormal.x, crvNormal.y, crvNormal.z); glBegin(GL_LINE_LOOP); for(int sliceItr = 0; sliceItr < numSlices; sliceItr++){ // quad vertex 4 rotateRadians = ((((float)sliceItr+1)/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint.x + (crvNormalRotated.x*radius), (float)crvPoint.y + (crvNormalRotated.y*radius), (float)crvPoint.z + (crvNormalRotated.z*radius)); // quad vertex 3 rotateRadians = ((((float)sliceItr+1)/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent2, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint2.x + (crvNormalRotated.x*radius2), (float)crvPoint2.y + (crvNormalRotated.y*radius2), (float)crvPoint2.z + (crvNormalRotated.z*radius2)); // quad vertex 2 rotateRadians = (((float)sliceItr/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent2, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint2.x + (crvNormalRotated.x*radius2), (float)crvPoint2.y + (crvNormalRotated.y*radius2), (float)crvPoint2.z + (crvNormalRotated.z*radius2)); // quad vertex 1 rotateRadians = (((float)sliceItr/numSlices)*360)*degreesToRadians; rotateQuat.setAxisAngle(crvTangent, rotateRadians); crvNormalRotated = crvNormal.rotateBy(rotateQuat); glNormal3f(crvNormalRotated.x, crvNormalRotated.y, crvNormalRotated.z ); glVertex3f((float)crvPoint.x + (crvNormalRotated.x*radius), (float)crvPoint.y + (crvNormalRotated.y*radius), (float)crvPoint.z + (crvNormalRotated.z*radius)); } glEnd(); } glPopAttrib(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // END WIREFRAME ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // glEnable(GL_LIGHT0); view.endGL(); }