MMatrix sgLockAngleMatrix::getsgLockAngleMatrix( const MMatrix& inputMatrix, unsigned char axis, double angle ) { MStatus status; angle = angle/180 * PI; bool minusAxis = false; if( axis > 2 ) { minusAxis = true; axis -= 3; } unsigned int upAxis = ( axis+1 ) % 3; unsigned int crossAxis = ( axis+2 ) % 3; MVector vDefault( 0,0,0 ); vDefault[ axis ] = 1; MVector vAxis = inputMatrix[ axis ]; vAxis.normalize(); double dotValue = vAxis * vDefault; double cuAngle = acos( dotValue ); if( angle > cuAngle ) angle = cuAngle; MVector vCross = vDefault ^ vAxis; MVector vUp = vCross ^ vDefault; vUp.normalize(); MVector vEdit = sin( angle ) * vUp + cos( angle ) * vDefault; if( minusAxis ) vEdit *= -1; MVector vUpEdit; vUpEdit[ axis ] = -vEdit[ upAxis ]; vUpEdit[ upAxis ] = vEdit[ axis ]; vUpEdit[ crossAxis ] = 0; MVector vCrossEdit = vEdit ^ vUpEdit; vUpEdit = vCrossEdit ^ vEdit; vEdit.normalize(); vUpEdit.normalize(); vCrossEdit.normalize(); MMatrix returnMtx; returnMtx( axis, 0 ) = vEdit.x; returnMtx( axis, 1 ) = vEdit.y; returnMtx( axis, 2 ) = vEdit.z; returnMtx( upAxis, 0 ) = vUpEdit.x; returnMtx( upAxis, 1 ) = vUpEdit.y; returnMtx( upAxis, 2 ) = vUpEdit.z; returnMtx( crossAxis, 0 ) = vCrossEdit.x; returnMtx( crossAxis, 1 ) = vCrossEdit.y; returnMtx( crossAxis, 2 ) = vCrossEdit.z; return returnMtx; }
void NurbsCurveEmitter::Fill(const FieldRef& field) { MFnNurbsCurve curve(mObject); // Get the range for U and V. MPlug minValuePlug = curve.findPlug("minValue"); MPlug maxValuePlug = curve.findPlug("maxValue"); const Double minValue = minValuePlug.asDouble(); const Double maxValue = maxValuePlug.asDouble(); const Double valueRange = maxValue - minValue; int i = 0; for (i = 0; i < static_cast<int>(mSample); ++ i) { double u = Stokes::Random::NextAsDouble(); double v = Stokes::Random::NextAsDouble(); double w = Stokes::Random::NextAsDouble(); double param = u * valueRange + minValue; MPoint p; curve.getPointAtParam(param, p, MSpace::kWorld); MVector t = curve.tangent(param, MSpace::kWorld); t.normalize(); MVector n = curve.normal(param, MSpace::kWorld); n.normalize(); MVector b = n ^ t; double r = sqrt(v); double phi = w * 2.0 * M_PI; double x = r * cos(phi); double y = r * sin(phi); // TODO: No radius here. MPoint newP = p + n * x + b * y; MVector radialDirection = newP - p; radialDirection.normalize(); Stokes::Vectorf noisedPoint(Random::NextAsFloat() * mScale.x - mOffset.x, Random::NextAsFloat() * mScale.y - mOffset.y, static_cast<Float>(u) * mScale.z - mOffset.z); Float displacement = Stokes::Noiser::FractalBrownianMotion(noisedPoint, mDisplacedH, mDisplacedLacunarity, mDisplacedOctave) * mDisplacedAmplitude; MPoint displacedP = newP + radialDirection * displacement; Stokes::Vectorf worldPoint(static_cast<Stokes::Float>(displacedP.x), static_cast<Stokes::Float>(displacedP.y), static_cast<Stokes::Float>(displacedP.z)); Stokes::Vectoriu index; if (field->CalculateIndexFromWorldPoint(worldPoint, index)) { Float density = Stokes::Noiser::FractalBrownianMotion(noisedPoint, mH, mLacunarity, mOctave) * mAmplitude; if (density > 0) { field->Access(index)[0] += density; } } } }
void splineSolverNode::gsOrthonormalize( MVector &normal, MVector &tangent ) { // Gram-Schmidt Orthonormalization normal.normalize(); MVector proj = normal * ( tangent * normal ); // normal * dotProduct(tangent,normal) tangent = tangent - proj; tangent.normalize(); }
MStatus AimNode::compute(const MPlug& plug, MDataBlock& dataBlock) { MStatus status; if ((plug == aOutputRotate) || (plug == aOutputRotateX) || (plug == aOutputRotateY) || (plug == aOutputRotateZ)) { // the matrix to aim at MMatrix driverMatrix = dataBlock.inputValue(aDriverMatrix).asMatrix(); // the matrix to use as the upVector MMatrix upVectorMatrix = dataBlock.inputValue(aUpVectorMatrix).asMatrix(); MVector inputTranslate = dataBlock.inputValue(aInputTranslate).asVector(); MMatrix parentInverse = dataBlock.inputValue(aParentInverseMatrix).asMatrix(); driverMatrix *= parentInverse; upVectorMatrix *= parentInverse; //extract the translation from the matrices MVector driverMatrixPos(driverMatrix[3][0], driverMatrix[3][1], driverMatrix[3][2]); MVector upVectorMatrixPos(upVectorMatrix[3][0], upVectorMatrix[3][1], upVectorMatrix[3][2]); //get the vectors MVector aimVector = driverMatrixPos - inputTranslate; MVector upVector = upVectorMatrixPos - inputTranslate; //upVector *= parentInverse; aimVector.normalize(); upVector.normalize(); //perpendicter vector MVector cross = aimVector ^ upVector; upVector = cross ^ aimVector; //build rotationMatrix double tmpMatrix[4][4]{{aimVector.x, aimVector.y, aimVector.z, 0}, {upVector.x, upVector.y, upVector.z, 0}, {cross.x, cross.y, cross.z, 0}, {inputTranslate[0], inputTranslate[1], inputTranslate[2], 1}}; //eulerRotations MMatrix rotationMatrix(tmpMatrix); MTransformationMatrix matrixfn(rotationMatrix); MEulerRotation eular = matrixfn.eulerRotation(); dataBlock.outputValue(aOutputRotate).set(eular.x, eular.y, eular.z); dataBlock.outputValue(aOutputRotate).setClean(); } return MS::kSuccess; }
MStatus sgHair_controlJoint::getJointPositionBaseWorld() { MStatus status; if( !m_bStaticRotation ) { MVector vAim; MVector vUp( m_mtxJointParentBase(1,0), m_mtxJointParentBase(1,1), m_mtxJointParentBase(1,2) ); MVector vCross; MMatrix mtxLocal; MMatrix mtxWorld = m_mtxJointParentBase; m_mtxArrBase.setLength( m_cvs.length() ); for( int i=0; i< m_cvs.length()-1; i++ ) { vAim = ( m_cvs[i+1] - m_cvs[i] )*m_mtxBaseCurve; vCross = vAim ^ vUp; vUp = vCross ^ vAim; vAim.normalize(); vUp.normalize(); vCross.normalize(); m_mtxArrBase[i] = buildMatrix( vAim, vUp, vCross, m_cvs[i]*m_mtxBaseCurve ); } MPoint pointWorld = m_cvs[m_cvs.length()-1]*m_mtxBaseCurve; MMatrix mtxLastWorld; mtxLastWorld( 3, 0 ) = pointWorld.x; mtxLastWorld( 3, 1 ) = pointWorld.y; mtxLastWorld( 3, 2 ) = pointWorld.z; m_mtxArrBase[m_cvs.length()-1] = mtxLastWorld; } else { MVector aim( 1,0,0 ); MVector up( 0,1,0 ); MVector cross( 0,0,1 ); m_mtxArrBase.setLength( m_cvs.length() ); aim *= m_mtxJointParentBase; up *= m_mtxJointParentBase; cross *= m_mtxJointParentBase; for( int i=0; i< m_cvs.length(); i++ ) { m_mtxArrBase[i] = buildMatrix( aim, up, cross, m_cvs[i]*m_mtxBaseCurve ); } } return MS::kSuccess; }
void CreateMatrix(const MPoint& origin, const MVector& normal, const MVector& up, MMatrix& matrix) { const MPoint& t = origin; const MVector& y = normal; MVector x = y ^ up; MVector z = x ^ y; // Renormalize vectors x.normalize(); z.normalize(); matrix[0][0] = x.x; matrix[0][1] = x.y; matrix[0][2] = x.z; matrix[0][3] = 0.0; matrix[1][0] = y.x; matrix[1][1] = y.y; matrix[1][2] = y.z; matrix[1][3] = 0.0; matrix[2][0] = z.x; matrix[2][1] = z.y; matrix[2][2] = z.z; matrix[2][3] = 0.0; matrix[3][0] = t.x; matrix[3][1] = t.y; matrix[3][2] = t.z; matrix[3][3] = 1.0; }
void exportTerrain::printLightData(const MFnLight& theLight){ fout << "Color: " << theLight.intensity()*theLight.color() << endl; MVector dir = theLight.lightDirection( 0, MSpace::kWorld); dir.normalize(); fout << "Direction: " << dir << endl; }
char BCIViz::checkFirstFour(const MPointArray & p) const { const MVector e01 = p[1] - p[0]; const MVector e02 = p[2] - p[0]; MVector nor = e01^e02; nor.normalize(); const float d = -(MVector(p[0])*nor); // P.N + d = 0 , P = P0 + Vt, (P0 + Vt).N + d = 0, t = -(P0.N + d)/(V.N) const float t = MVector(p[3])*nor + d; // where V = -N if(t > -10e-5 && t < 10e-5) return 0; return 1; }
void n_tentacle::removeMatrixScale(MMatrix &matrix) { MVector axisX = MVector(matrix(0, 0), matrix(0, 1), matrix(0, 2)); MVector axisY = MVector(matrix(1, 0), matrix(1, 1), matrix(1, 2)); MVector axisZ = MVector(matrix(2, 0), matrix(2, 1), matrix(2, 2)); axisX.normalize(); axisY.normalize(); axisZ.normalize(); matrix[0][0] = axisX.x; matrix[0][1] = axisX.y; matrix[0][2] = axisX.z; matrix[1][0] = axisY.x; matrix[1][1] = axisY.y; matrix[1][2] = axisY.z; matrix[2][0] = axisZ.x; matrix[2][1] = axisZ.y; matrix[2][2] = axisZ.z; }
void sgHair_controlJoint::cleanMatrix( MMatrix& mtx ) { MVector vAim( mtx(0,0), mtx(0,1), mtx(0,2) ); MVector vUp( mtx(1,0), mtx(1,1), mtx(1,2) ); MVector vCross = vAim ^ vUp; vUp = vCross ^ vAim; vAim.normalize(); vUp.normalize(); vCross.normalize(); mtx( 0, 0 ) = vAim.x; mtx( 0, 1 ) = vAim.y; mtx( 0, 2 ) = vAim.z; mtx( 1, 0 ) = vUp.x; mtx( 1, 1 ) = vUp.y; mtx( 1, 2 ) = vUp.z; mtx( 2, 0 ) = vCross.x; mtx( 2, 1 ) = vCross.y; mtx( 2, 2 ) = vCross.z; }
MVector MG_poseReader::matrixToAxisMatrix (const int &aimAxis , const MMatrix &matrix,const int normalize){ MVector toVec; switch ( aimAxis ) { case 0: if (aimAxis==0) { toVec[0]=matrix[0][0]; toVec[1]=matrix[0][1]; toVec[2]=matrix[0][2]; } case 1: if (aimAxis==1) { toVec[0]=matrix[1][0]; toVec[1]=matrix[1][1]; toVec[2]=matrix[1][2]; } case 2: if (aimAxis==2) { toVec[0]=matrix[2][0]; toVec[1]=matrix[2][1]; toVec[2]=matrix[2][2]; } } toVec.normalize(); return toVec; }
void GetValidUp(const MDoubleArray& weights, const MPointArray& points, const MIntArray& sampleIds, const MPoint& origin, const MVector& normal, MVector& up) { MVector unitUp = up.normal(); // Adjust up if it's parallel to normal or if it's zero length if (std::abs((unitUp * normal) - 1.0) < 0.001 || up.length() < 0.0001) { for (unsigned int j = 0; j < weights.length()-1; ++j) { up -= (points[sampleIds[j]] - origin) * weights[j]; unitUp = up.normal(); if (std::abs((unitUp * normal) - 1.0) > 0.001 && up.length() > 0.0001) { // If the up and normal vectors are no longer parallel and the up vector has a length, // then we are good to go. break; } } up.normalize(); } else { up = unitUp; } }
MMatrix retargetLocator::getAimMatrix( MMatrix inputAimMatrix ) { MVector aimVector( inputAimMatrix(3,0), inputAimMatrix(3,1), inputAimMatrix(3,2) ); aimVector -= discOffset; MVector upVector( -aimVector.y - aimVector.z, aimVector.x, aimVector.x ); MVector otherVector = aimVector^upVector; upVector = otherVector^aimVector; MVector normalizeAim = aimVector.normal(); upVector.normalize(); otherVector.normalize(); aimVector += discOffset; double buildMatrix[4][4] = { normalizeAim.x, normalizeAim.y, normalizeAim.z, 0, upVector.x, upVector.y, upVector.z, 0, otherVector.x, otherVector.y, otherVector.z, 0, aimVector.x, aimVector.y, aimVector.z, 1 }; return MMatrix( buildMatrix ); }
MMatrix sgHair_controlJoint::getAngleWeightedMatrix( const MMatrix& targetMtx, double weight ) { MMatrix mtx; if( m_bStaticRotation ) { mtx = MMatrix() * ( weight-1 ) + targetMtx * weight; cleanMatrix( mtx ); } else { MVector vUpDefault( 0, 1, 0 ); MVector vCrossDefault( 0,0,1 ); MVector vUpInput( targetMtx(1,0), targetMtx(1,1), targetMtx(1,2) ); double angleUp = vUpInput.angle( vUpDefault ) * weight; if( vUpInput.x == 0 && vUpInput.z == 0 ) vUpInput.x = 1; MVector direction( vUpInput.x, 0, vUpInput.z ); direction.normalize(); MVector vUp( sin( angleUp ) * direction.x, cos( angleUp ), sin( angleUp ) * direction.z ); double dot = vUp * MVector( 0.0, 0.0, 1.0 ); MVector vCross( 0.0, -dot, (dot+1) ); MVector vAim = vUp ^ vCross; vAim.normalize(); vUp.normalize(); vCross = vAim ^ vUp; mtx( 0, 0 ) = vAim.x; mtx( 0, 1 ) = vAim.y; mtx( 0, 2 ) = vAim.z; mtx( 1, 0 ) = vUp.x; mtx( 1, 1 ) = vUp.y; mtx( 1, 2 ) = vUp.z; mtx( 2, 0 ) = vCross.x; mtx( 2, 1 ) = vCross.y; mtx( 2, 2 ) = vCross.z; } return mtx; }
void CylinderMesh::transform(MPointArray& points, MVectorArray& normals) { MVector forward = mEnd - mStart; double s = forward.length(); forward.normalize(); MVector left = MVector(0,0,1)^forward; MVector up; if (left.length() < 0.0001) { up = forward^MVector(0,1,0); left = up^forward; } else { up = forward^left; } MMatrix mat; mat[0][0] = forward[0]; mat[0][1] = left[0]; mat[0][2] = up[0]; mat[0][3] = 0; mat[1][0] = forward[1]; mat[1][1] = left[1]; mat[1][2] = up[1]; mat[1][3] = 0; mat[2][0] = forward[2]; mat[2][1] = left[2]; mat[2][2] = up[2]; mat[2][3] = 0; mat[3][0] = 0; mat[3][1] = 0; mat[3][2] = 0; mat[3][3] = 1; mat = mat.transpose(); for (int i = 0; i < gPoints.length(); i++) { MPoint p = gPoints[i]; p.x = p.x * s; // scale p = p * mat + mStart; // transform points.append(p); MVector n = gNormals[i] * mat; normals.append(n); } }
MStatus MG_softIk::compute(const MPlug& plug,MDataBlock& dataBlock) { //Get data if ((plug == outputTranslate) ||(plug == downScale) ||(plug == upScale) ) { MMatrix startMatrixV = dataBlock.inputValue(startMatrix).asMatrix(); MMatrix endMatrixV = dataBlock.inputValue(endMatrix).asMatrix(); double upInitLengthV = dataBlock.inputValue(upInitLength).asDouble(); double downInitLengthV = dataBlock.inputValue(downInitLength).asDouble(); double softDistanceV = dataBlock.inputValue(softDistance).asDouble(); double stretchV= dataBlock.inputValue(stretch).asDouble(); double slideV = dataBlock.inputValue(slide).asDouble(); double globalScaleV = dataBlock.inputValue(globalScale).asDouble(); upInitLengthV = upInitLengthV*(slideV*2)*globalScaleV ; downInitLengthV = downInitLengthV*((1 - slideV)*2)*globalScaleV; double chainLength = upInitLengthV + downInitLengthV ; MVector startVector (startMatrixV[3][0] , startMatrixV[3][1] , startMatrixV[3][2] ); MVector endVector (endMatrixV[3][0] , endMatrixV[3][1] , endMatrixV[3][2] ); MVector currentLengthVector = endVector - startVector ; double currentLength = currentLengthVector.length() ; double startSD = chainLength - softDistanceV; double stretchParam = 1; double upScaleOut = 1 ; double downScaleOut = 1 ; if (startSD <= currentLength) { if (softDistanceV != 0 ) { double expParam = ( currentLength - startSD) / softDistanceV; expParam*= -1 ; double softLength = ( (softDistanceV *(1 - exp ( expParam)) )+ startSD ); currentLengthVector.normalize(); currentLengthVector*=softLength ; if (stretchV != 0 ) { stretchParam = (currentLength/softLength ); double delta = (stretchParam - 1); delta*=stretchV; stretchParam = 1*(1 + delta); currentLengthVector *=(1 + delta ); } } } //slide computing upScaleOut = (slideV*2) *stretchParam ; downScaleOut = ((1 - slideV)*2)*stretchParam; MVector outVec = startVector + currentLengthVector; dataBlock.outputValue(outputTranslate).setMVector(outVec); dataBlock.outputValue(outputTranslate).setClean(); dataBlock.outputValue(downScale).set(downScaleOut); dataBlock.outputValue(downScale).setClean(); dataBlock.outputValue(upScale).set(upScaleOut); dataBlock.outputValue(upScale).setClean(); } return MS::kSuccess; }
void WireExport::Export(string folder, string fileName) { MStatus stat; mFolder = folder; mFileName = fileName; mSaver.SetFolder(mFolder); MItDependencyNodes itRenderLayers(MFn::kRenderLayer,&stat); err_code(stat); MFnRenderLayer wireLayer; while (!itRenderLayers.isDone()) { MFnRenderLayer renderLayer( itRenderLayers.item() ); if (renderLayer.name() == "wire") { stat = wireLayer.setObject( renderLayer.object() ); err_code(stat); break; } stat = itRenderLayers.next(); err_code(stat); } MItDependencyNodes itDepCurve(MFn::kNurbsCurve,&stat); err_code(stat); vector<Wire> wires; while (!itDepCurve.isDone()) { MObject obj = itDepCurve.item(); MFnNurbsCurve wire(obj, &stat); err_code(stat); bool objInLayer = wireLayer.inLayer(obj, &stat); //err_code(stat); if (!objInLayer) { stat = itDepCurve.next(); err_code(stat); continue; } MString cmd = MString("reference -q -f ") + wire.name(); MString file_id; stat = MGlobal::executeCommand( cmd, file_id ); if( stat == MS::kSuccess ) { itDepCurve.next(); continue; } MObject parentObj = wire.parent(0, &stat); err_code(stat); Wire newWire; newWire.name = wire.name().asChar(); MPointArray points; stat = wire.getCVs(points); err_code(stat); int numOfPoints = points.length(); for (int n = 0; n < numOfPoints ; n++) { MPoint point = points[n]; WirePoint wirePoint; wirePoint.x = (float)point.x; wirePoint.z = (float)point.z; double param; stat = wire.getParamAtPoint( point, param ); err_code(stat); MVector tangent = wire.tangent( param , MSpace::kObject, &stat); err_code(stat); tangent.normalize(); wirePoint.tx = (float)tangent.x; wirePoint.tz = (float)tangent.z; newWire.wirePoints.push_back(wirePoint); } wires.push_back(newWire); stat = itDepCurve.next(); err_code(stat); } WriteWires(wires); }
void ExportACache::save(const char* filename, int frameNumber, char bfirst) { MStatus status; FXMLScene xml_f; xml_f.begin(filename, frameNumber, bfirst); for(unsigned it=0; it<m_mesh_list.length(); it++) { m_mesh_list[it].extendToShape(); MString surface = m_mesh_list[it].partialPathName(); AHelper::validateFilePath(surface); MFnDependencyNode fnode(m_mesh_list[it].node()); MString smsg("prtMsg"); MStatus hasMsg; MPlug pmsg = fnode.findPlug( smsg, 1, &hasMsg ); char bNoChange = 0; if(hasMsg) { MObject oattrib; AHelper::getConnectedNode(oattrib, pmsg); fnode.setObject(oattrib); bool iattr = 0; AHelper::getBoolAttributeByName(fnode, "noChange", iattr); if(iattr) bNoChange = 1; } xml_f.meshBegin(surface.asChar(), bNoChange); MFnMesh meshFn(m_mesh_list[it], &status ); MItMeshPolygon faceIter(m_mesh_list[it], MObject::kNullObj, &status ); MItMeshVertex vertIter(m_mesh_list[it], MObject::kNullObj, &status); MItMeshEdge edgeIter(m_mesh_list[it], MObject::kNullObj, &status); int n_tri = 0; float f_area = 0; double area; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { MIntArray vexlist; faceIter.getVertices ( vexlist ); n_tri += vexlist.length() - 2; faceIter.getArea( area, MSpace::kWorld ); f_area += (float)area; } xml_f.triangleInfo(n_tri, f_area); float avg_grid = sqrt(f_area/n_tri)/2; double light_intensity = 1.0; if(hasMsg) { MObject oattrib; AHelper::getConnectedNode(oattrib, pmsg); fnode.setObject(oattrib); bool iattr = 0; AHelper::getBoolAttributeByName(fnode, "noChange", iattr); if(iattr) xml_f.addAttribute("noChange", 1); AHelper::getBoolAttributeByName(fnode, "skipIndirect", iattr); if(iattr) xml_f.addAttribute("skipIndirect", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "skipScatter", iattr); if(iattr) xml_f.addAttribute("skipScatter", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "skipBackscatter", iattr); if(iattr) xml_f.addAttribute("skipBackscatter", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "asLightsource", iattr); if(iattr) xml_f.addAttribute("asLightsource", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "asGhost", iattr); if(iattr) xml_f.addAttribute("invisible", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "castNoShadow", iattr); if(iattr) xml_f.addAttribute("noShadow", 1); double td; if(AHelper::getDoubleAttributeByName(fnode, "lightIntensity", td)) light_intensity = td; fnode.setObject(m_mesh_list[it].node()); } xml_f.staticBegin(); int n_poly = meshFn.numPolygons(); int n_vert = meshFn.numVertices(); int* polycount = new int[n_poly]; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) polycount[ faceIter.index() ] = faceIter.polygonVertexCount(); xml_f.addFaceCount(n_poly, polycount); delete[] polycount; int n_facevertex = meshFn.numFaceVertices(); int* polyconnect = new int[n_facevertex]; int acc = 0; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { MIntArray vexlist; faceIter.getVertices ( vexlist ); for( int i=vexlist.length()-1; i >=0; i-- ) { polyconnect[acc] = vexlist[i]; acc++; } } xml_f.addFaceConnection(n_facevertex, polyconnect); delete[] polyconnect; int* triconnect = new int[3*n_tri]; acc = 0; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { MIntArray vexlist; faceIter.getVertices ( vexlist ); for( int i=vexlist.length()-2; i >0; i-- ) { triconnect[acc] = vexlist[vexlist.length()-1]; acc++; triconnect[acc] = vexlist[i]; acc++; triconnect[acc] = vexlist[i-1]; acc++; } } xml_f.addTriangleConnection(3*n_tri, triconnect); delete[] triconnect; if(meshFn.numUVSets() > 0) { MStringArray setNames; meshFn.getUVSetNames(setNames); for(unsigned i=0; i< setNames.length(); i++) { float* scoord = new float[n_facevertex]; float* tcoord = new float[n_facevertex]; acc = 0; faceIter.reset(); MFloatArray uarray, varray; if(faceIter.hasUVs (setNames[i], &status)) { for( ; !faceIter.isDone(); faceIter.next() ) { faceIter.getUVs ( uarray, varray, &setNames[i] ); for( int j=uarray.length()-1; j >=0 ; j-- ) { scoord[acc] = uarray[j]; tcoord[acc] = 1.0 - varray[j]; acc++; } } if(setNames[i] == "map1") { xml_f.uvSetBegin(setNames[i].asChar()); xml_f.addS("facevarying float s", meshFn.numFaceVertices(), scoord); xml_f.addT("facevarying float t", meshFn.numFaceVertices(), tcoord); xml_f.uvSetEnd(); } else { xml_f.uvSetBegin(setNames[i].asChar()); std::string paramname("facevarying float u_"); paramname.append(setNames[i].asChar()); xml_f.addS(paramname.c_str(), meshFn.numFaceVertices(), scoord); paramname = "facevarying float v_"; paramname.append(setNames[i].asChar()); xml_f.addT(paramname.c_str(), meshFn.numFaceVertices(), tcoord); xml_f.uvSetEnd(); } } else MGlobal::displayWarning(MString("Skip empty uv set: ") + setNames[i]); delete[] scoord; delete[] tcoord; } } MStringArray colorSetNames; meshFn.getColorSetNames (colorSetNames); for(unsigned int i=0; i<colorSetNames.length(); i++) { MStatus hasColor; XYZ *colors = new XYZ[n_vert]; vertIter.reset(); MString aset = colorSetNames[i]; MColor col; for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray conn_face; vertIter.getConnectedFaces(conn_face); vertIter.getColor(col, conn_face[0], &aset); colors[i].x = col.r*light_intensity; colors[i].y = col.g*light_intensity; colors[i].z = col.b*light_intensity; } xml_f.addVertexColor(aset.asChar(), n_vert, colors); delete[] colors; } //if(!bNoChange) { //} MPointArray p_vert; meshFn.getPoints ( p_vert, MSpace::kWorld ); MPoint corner_l(10e6, 10e6, 10e6); MPoint corner_h(-10e6, -10e6, -10e6); for( unsigned int i=0; i<p_vert.length(); i++) { if( p_vert[i].x < corner_l.x ) corner_l.x = p_vert[i].x; if( p_vert[i].y < corner_l.y ) corner_l.y = p_vert[i].y; if( p_vert[i].z < corner_l.z ) corner_l.z = p_vert[i].z; if( p_vert[i].x > corner_h.x ) corner_h.x = p_vert[i].x; if( p_vert[i].y > corner_h.y ) corner_h.y = p_vert[i].y; if( p_vert[i].z > corner_h.z ) corner_h.z = p_vert[i].z; } XYZ *cv = new XYZ[n_vert]; for( unsigned int i=0; i<p_vert.length(); i++) { cv[i].x = p_vert[i].x; cv[i].y = p_vert[i].y; cv[i].z= p_vert[i].z; } //if(!bNoChange) //else xml_f.addStaticP(n_vert, cv); XYZ *nor = new XYZ[n_vert]; XYZ *tang = new XYZ[n_vert]; vertIter.reset(); MVector vnor; for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { vertIter.getNormal(vnor, MSpace::kWorld); vnor.normalize(); nor[i].x = vnor.x; nor[i].y = vnor.y; nor[i].z = vnor.z; } MString uvset("map1"); vertIter.reset(); for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray conn_face; vertIter.getConnectedFaces(conn_face); MVector ctang(0,0,0); MVector ttang; for(unsigned j = 0; j<conn_face.length(); j++) { meshFn.getFaceVertexTangent (conn_face[j], i, ttang, MSpace::kWorld, &uvset); ttang.normalize(); ctang += ttang; } ctang.normalize(); tang[i].x = ctang.x; tang[i].y = ctang.y; tang[i].z = ctang.z; tang[i] = nor[i].cross(tang[i]); tang[i].normalize(); } //if(!bNoChange) //else xml_f.addStaticN(n_vert, nor); //xml_f.addTangent(n_vert, tang); // export per-vertex thickness float* vgrd = new float[n_vert]; int pidx; vertIter.reset(); for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray connfaces; vertIter.getConnectedFaces( connfaces ); float connarea = 0; for(unsigned j=0; j<connfaces.length(); j++) { faceIter.setIndex(connfaces[j], pidx); faceIter.getArea(area, MSpace::kWorld ); connarea += (float)area/faceIter.polygonVertexCount(); } vgrd[i] = sqrt(connarea)/2; if(vgrd[i] > avg_grid) vgrd[i] = avg_grid; } //if(!bNoChange) //else xml_f.addStaticGridSize(n_vert, vgrd); // //else xml_f.staticEnd(); if(!bNoChange) { xml_f.dynamicBegin(); xml_f.addP(n_vert, cv); xml_f.addN(n_vert, nor); xml_f.addGridSize(n_vert, vgrd); xml_f.dynamicEnd(); } delete[] cv; delete[] tang; delete[] nor; delete[] vgrd; xml_f.addBBox(corner_l.x, corner_l.y, corner_l.z, corner_h.x, corner_h.y, corner_h.z); xml_f.meshEnd(bNoChange); } /* disable nurbs for now float aspace[4][4]; for(unsigned it=0; it<m_nurbs_list.length(); it++) { MVector scale = AHelper::getTransformWorldNoScale(m_nurbs_list[it].fullPathName(), aspace); MString surfacename = m_nurbs_list[it].fullPathName(); AHelper::validateFilePath(surfacename); xml_f.transformBegin(surfacename.asChar(), aspace); xml_f.addScale(scale.x, scale.y, scale.z); m_nurbs_list[it].extendToShape(); surfacename = m_nurbs_list[it].fullPathName(); AHelper::validateFilePath(surfacename); MFnNurbsSurface fsurface(m_nurbs_list[it]); int degreeU = fsurface.degreeU(); int degreeV = fsurface.degreeV(); int formU, formV; if(fsurface.formInU() == MFnNurbsSurface::kOpen ) formU = 0; else if(fsurface.formInU() == MFnNurbsSurface::kClosed ) formU = 1; else formU = 2; if(fsurface.formInV() == MFnNurbsSurface::kOpen ) formV = 0; else if(fsurface.formInV() == MFnNurbsSurface::kClosed ) formV = 1; else formV = 2; xml_f.nurbssurfaceBegin(surfacename.asChar(), degreeU, degreeV, formU, formV); xml_f.staticBegin(); MPointArray p_cvs; fsurface.getCVs( p_cvs, MSpace::kObject ); unsigned n_cvs = p_cvs.length(); XYZ *cv = new XYZ[n_cvs]; for(unsigned i=0; i<n_cvs; i++) { cv[i].x = p_cvs[i].x; cv[i].y = p_cvs[i].y; cv[i].z= p_cvs[i].z; } xml_f.addStaticVec("cvs", n_cvs, cv); delete[] cv; MDoubleArray knotu, knotv; fsurface.getKnotsInU(knotu); fsurface.getKnotsInV(knotv); unsigned n_ku = knotu.length(); unsigned n_kv = knotv.length(); float *ku = new float[n_ku]; for(unsigned i=0; i<n_ku; i++) ku[i] = knotu[i]; float *kv = new float[n_kv]; for(unsigned i=0; i<n_kv; i++) kv[i] = knotv[i]; xml_f.addStaticFloat("knotu", n_ku, ku); xml_f.addStaticFloat("knotv", n_kv, kv); delete[] ku; delete[] kv; xml_f.staticEnd(); xml_f.nurbssurfaceEnd(); xml_f.transformEnd(); } */ xml_f.cameraBegin("backscat_camera", m_space); xml_f.cameraEnd(); xml_f.cameraBegin("eye_camera", m_eye); p_eye.extendToShape(); MFnCamera feye(p_eye); xml_f.addAttribute("focal_length", (float)feye.focalLength()); xml_f.addAttribute("horizontal_film_aperture", (float)feye.horizontalFilmAperture()); xml_f.addAttribute("vertical_film_aperture", (float)feye.verticalFilmAperture()); xml_f.addAttribute("near_clipping_plane", (float)feye.nearClippingPlane()); xml_f.addAttribute("far_clipping_plane", (float)feye.farClippingPlane()); xml_f.cameraEnd(); xml_f.end(filename); }
// COMPUTE ====================================== MStatus gear_slideCurve2::deform( MDataBlock& data, MItGeometry& iter, const MMatrix &mat, unsigned int mIndex ) { MStatus returnStatus; // Inputs --------------------------------------------------------- // Input NurbsCurve // Curve MFnNurbsCurve crv( data.inputValue( master_crv ).asNurbsCurve() ); MMatrix m = data.inputValue(master_mat).asMatrix(); // Input Sliders double in_sl = (double)data.inputValue(slave_length).asFloat(); double in_ml = (double)data.inputValue(master_length).asFloat(); double in_position = (double)data.inputValue(position).asFloat(); double in_maxstretch = (double)data.inputValue(maxstretch).asFloat(); double in_maxsquash = (double)data.inputValue(maxsquash).asFloat(); double in_softness = (double)data.inputValue(softness).asFloat(); // Init ----------------------------------------------------------- double mstCrvLength = crv.length(); int slvPointCount = iter.exactCount(); // Can we use .count() ? int mstPointCount = crv.numCVs(); // Stretch -------------------------------------------------------- double expo = 1; if ((mstCrvLength > in_ml) && (in_maxstretch > 1)){ if (in_softness != 0){ double stretch = (mstCrvLength - in_ml) / (in_sl * in_maxstretch); expo = 1 - exp(-(stretch) / in_softness); } double ext = min(in_sl * (in_maxstretch - 1) * expo, mstCrvLength - in_ml); in_sl += ext; } else if ((mstCrvLength < in_ml) && (in_maxsquash < 1)){ if (in_softness != 0){ double squash = (in_ml - mstCrvLength) / (in_sl * in_maxsquash); expo = 1 - exp(-(squash) / in_softness); } double ext = min(in_sl * (1 - in_maxsquash) * expo, in_ml - mstCrvLength); in_sl -= ext; } // Position -------------------------------------------------------- double size = in_sl / mstCrvLength; double sizeLeft = 1 - size; double start = in_position * sizeLeft; double end = start + size; double tStart, tEnd; crv.getKnotDomain(tStart, tEnd); // Process -------------------------------------------------------- double step = (end - start) / (slvPointCount - 1.0); MPoint pt; MVector tan; while (! iter.isDone()){ double perc = start + (iter.index() * step); double u = crv.findParamFromLength(perc * mstCrvLength); if ((0 <= perc) && (perc <= 1)) crv.getPointAtParam(u, pt, MSpace::kWorld); else{ double overPerc; if (perc < 0){ overPerc = perc; crv.getPointAtParam(0, pt, MSpace::kWorld); tan = crv.tangent(0); } else{ overPerc = perc - 1; crv.getPointAtParam(mstPointCount-3.0, pt, MSpace::kWorld); tan = crv.tangent(mstPointCount-3.0); tan.normalize(); tan *= mstCrvLength * overPerc; pt += tan; } } pt *= mat.inverse(); pt *= m; iter.setPosition(pt); iter.next(); } return MS::kSuccess; }
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; }
MStatus BCIViz::compute( const MPlug& plug, MDataBlock& block ) { if( plug == outValue ) { MStatus status; MDagPath path; MDagPath::getAPathTo(thisMObject(), path); MMatrix worldInverseSpace = path.inclusiveMatrixInverse(); MDataHandle inputdata = block.inputValue(ainput, &status); if(status) { const MMatrix drvSpace = inputdata.asMatrix(); fDriverPos.x = drvSpace(3, 0); fDriverPos.y = drvSpace(3, 1); fDriverPos.z = drvSpace(3, 2); fDriverPos *= worldInverseSpace; } fTargetPositions.clear(); MArrayDataHandle htarget = block.inputArrayValue( atargets ); unsigned numTarget = htarget.elementCount(); fTargetPositions.setLength(numTarget); for(unsigned i = 0; i<numTarget; i++) { MDataHandle tgtdata = htarget.inputValue(&status); if(status) { const MMatrix tgtSpace = tgtdata.asMatrix(); MPoint tgtPos(tgtSpace(3,0), tgtSpace(3,1), tgtSpace(3,2)); tgtPos *= worldInverseSpace; MVector disp = tgtPos; disp.normalize(); tgtPos = disp; fTargetPositions[i] = tgtPos; } htarget.next(); } m_hitTriangle = 0; neighbourId[0] = 0; neighbourId[1] = 1; neighbourId[2] = 2; if(!checkTarget()) { MGlobal::displayWarning("convex hull must have no less than 4 targes."); return MS::kSuccess; } if(!checkFirstFour(fTargetPositions)) { MGlobal::displayWarning("first 4 targes cannot sit on the same plane."); return MS::kSuccess; } if(!constructHull()) { MGlobal::displayWarning("convex hull failed on construction."); return MS::kSuccess; } findNeighbours(); calculateWeight(); MArrayDataHandle outputHandle = block.outputArrayValue( outValue ); int numWeight = fTargetPositions.length(); m_resultWeights.setLength(numWeight); for(int i=0; i < numWeight; i++) m_resultWeights[i] = 0.0; m_resultWeights[neighbourId[0]] = fAlpha; m_resultWeights[neighbourId[1]] = fBeta; m_resultWeights[neighbourId[2]] = fGamma; MArrayDataBuilder builder(outValue, numWeight, &status); for(int i=0; i < numWeight; i++) { MDataHandle outWeightHandle = builder.addElement(i); outWeightHandle.set( m_resultWeights[i] ); //MGlobal::displayInfo(MString("wei ") + i + " " + weights[i]); } outputHandle.set(builder); outputHandle.setAllClean(); } return MS::kSuccess; }
MObject VMesh::createFeather() { MStatus stat; MFnMeshData dataCreator; MObject outMeshData = dataCreator.create(&stat); int numVertex = 0; int numPolygon = 0; MPointArray vertexArray; MFloatArray uArray, vArray; MIntArray polygonCounts, polygonConnects, polygonUVs; MFnMesh meshFn(pgrow, &stat); MItMeshVertex vertIter(pgrow, &stat); MItMeshPolygon faceIter(pgrow, &stat); MPoint S; MVector N, tang, ttang, binormal, dir, hair_up; MColor Cscale, Cerect, Crotate, Ccurl, Cwidth; float rot, lengreal; MATRIX44F hair_space; MString setScale("fb_scale"); MString setErect("fb_erect"); MString setRotate("fb_rotate"); MString setCurl("fb_curl"); MString setWidth("fb_width"); MIntArray conn_face; for( int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { if(vertIter.onBoundary()) continue; vertIter.getNormal(N, MSpace::kWorld); N.normalize(); vertIter.getColor(Cscale, &setScale); vertIter.getColor(Cerect, &setErect); vertIter.getColor(Crotate, &setRotate); vertIter.getColor(Ccurl, &setCurl); vertIter.getColor(Cwidth, &setWidth); vertIter.getConnectedFaces(conn_face); tang = MVector(0,0,0); for(int j=0; j<conn_face.length(); j++) { meshFn.getFaceVertexTangent (conn_face[j], i, ttang, MSpace::kWorld); ttang.normalize(); tang += ttang; } tang /= conn_face.length(); conn_face.clear(); tang.normalize(); tang = N^tang; tang.normalize(); binormal = N^tang; if(Crotate.r<0.5) { rot = (0.5 - Crotate.r)*2; tang = tang + (binormal-tang)*rot; tang.normalize(); binormal = N^tang; } else { rot = (Crotate.r-0.5)*2; tang = tang + (binormal*-1-tang)*rot; tang.normalize(); binormal = N^tang; } dir = tang + (N - tang)*Cerect.r; dir.normalize(); //S = S+dir*Cscale.r*m_scale; //glVertex3f(S.x, S.y, S.z); hair_up = dir^binormal; hair_space.setIdentity(); hair_space.setOrientations(XYZ(binormal.x, binormal.y, binormal.z), XYZ(hair_up.x, hair_up.y, hair_up.z), XYZ(dir.x, dir.y, dir.z)); S = vertIter.position(MSpace::kWorld); hair_space.setTranslation(XYZ(S.x, S.y, S.z)); lengreal = Cscale.r*m_scale; fb->create(lengreal, 0, lengreal*(Ccurl.r-0.5)*2); XYZ pw; MPoint pvx; MPoint pright = S + binormal*Cwidth.r*m_width*lengreal; MPoint pleft = S - binormal*Cwidth.r*m_width*lengreal; MPoint phit; int polyhit; meshFn.getClosestPoint (pright, phit, MSpace::kObject, &polyhit); MVector topright = phit - S; topright.normalize(); topright *= Cwidth.r*m_width*lengreal; meshFn.getClosestPoint (pleft, phit, MSpace::kObject, &polyhit); MVector topleft = phit - S; topleft.normalize(); topleft *= Cwidth.r*m_width*lengreal; //tws_binormal = binormal*cos(0.2) + hair_up*sin(0.2); for(int j=0; j<NUMBENDSEG+1; j++) { fb->getPoint(j, pw); hair_space.transform(pw); pvx = MPoint(pw.x, pw.y, pw.z) + topleft;//- tws_binormal*Cwidth.r*m_width*lengreal; vertexArray.append(pvx); pvx = MPoint(pw.x, pw.y, pw.z); vertexArray.append(pvx); pvx = MPoint(pw.x, pw.y, pw.z) + topright;//tws_binormal*Cwidth.r*m_width*lengreal; vertexArray.append(pvx); uArray.append(0.0); vArray.append((float)j/NUMBENDSEG); uArray.append(0.5); vArray.append((float)j/NUMBENDSEG); uArray.append(1.0); vArray.append((float)j/NUMBENDSEG); } for(int j=0; j<NUMBENDSEG; j++) { polygonConnects.append(j*3 + numVertex); polygonConnects.append(j*3+3 + numVertex); polygonConnects.append(j*3+4 + numVertex); polygonConnects.append(j*3+1 + numVertex); polygonCounts.append(4); polygonConnects.append(j*3+1 + numVertex); polygonConnects.append(j*3+4 + numVertex); polygonConnects.append(j*3+5 + numVertex); polygonConnects.append(j*3+2 + numVertex); polygonCounts.append(4); polygonUVs.append(j*3 + numVertex); polygonUVs.append(j*3+3 + numVertex); polygonUVs.append(j*3+4 + numVertex); polygonUVs.append(j*3+1 + numVertex); polygonUVs.append(j*3+1 + numVertex); polygonUVs.append(j*3+4 + numVertex); polygonUVs.append(j*3+5 + numVertex); polygonUVs.append(j*3+2 + numVertex); } numVertex += (NUMBENDSEG+1)*3; numPolygon += NUMBENDSEG*2; } MIntArray connvert; int idxpre; float averg_scale, averg_erect, averg_rotate, averg_curl, averg_width; for( int i=0; !faceIter.isDone(); faceIter.next(), i++ ) { if(faceIter.onBoundary()) continue; faceIter.getNormal(N, MSpace::kWorld); N.normalize(); faceIter.getVertices(connvert); averg_scale=averg_erect=averg_rotate=averg_curl=0; for(int j=0; j<connvert.length(); j++) { vertIter.setIndex(connvert[j], idxpre); vertIter.getColor(Cscale, &setScale); vertIter.getColor(Cerect, &setErect); vertIter.getColor(Crotate, &setRotate); vertIter.getColor(Ccurl, &setCurl); vertIter.getColor(Cwidth, &setWidth); averg_scale += Cscale.r; averg_erect += Cerect.r; averg_rotate += Crotate.r; averg_curl += Ccurl.r; averg_width += Cwidth.r; } averg_scale /= connvert.length(); averg_erect /= connvert.length(); averg_rotate /= connvert.length(); averg_curl /= connvert.length(); averg_width /= connvert.length(); tang = MVector(0,0,0); for(int j=0; j<connvert.length(); j++) { meshFn.getFaceVertexTangent (i, connvert[j], ttang, MSpace::kWorld); ttang.normalize(); tang += ttang; } //tang /= conn_face.length(); connvert.clear(); tang.normalize(); tang = N^tang; tang.normalize(); binormal = N^tang; if(averg_rotate<0.5) { rot = (0.5 - averg_rotate)*2; tang = tang + (binormal-tang)*rot; tang.normalize(); binormal = N^tang; } else { rot = (averg_rotate-0.5)*2; tang = tang + (binormal*-1-tang)*rot; tang.normalize(); binormal = N^tang; } dir = tang + (N - tang)*averg_erect; dir.normalize(); //S = S+dir*Cscale.r*m_scale; //glVertex3f(S.x, S.y, S.z); hair_up = dir^binormal; hair_space.setIdentity(); hair_space.setOrientations(XYZ(binormal.x, binormal.y, binormal.z), XYZ(hair_up.x, hair_up.y, hair_up.z), XYZ(dir.x, dir.y, dir.z)); S = faceIter.center(MSpace::kWorld); hair_space.setTranslation(XYZ(S.x, S.y, S.z)); lengreal = Cscale.r*m_scale; fb->create(lengreal, 0, lengreal*(averg_curl-0.5)*2); MPoint pright = S + binormal*Cwidth.r*m_width*lengreal; MPoint pleft = S - binormal*Cwidth.r*m_width*lengreal; XYZ pw; MPoint pvx; MPoint phit; int polyhit; meshFn.getClosestPoint (pright, phit, MSpace::kObject, &polyhit); MVector topright = phit - S; topright.normalize(); topright *= Cwidth.r*m_width*lengreal; meshFn.getClosestPoint (pleft, phit, MSpace::kObject, &polyhit); MVector topleft = phit - S; topleft.normalize(); topleft *= Cwidth.r*m_width*lengreal; //tws_binormal = binormal*cos(0.2) + hair_up*sin(0.2); for(int j=0; j<NUMBENDSEG+1; j++) { fb->getPoint(j, pw); hair_space.transform(pw); pvx = MPoint(pw.x, pw.y, pw.z) + topleft;//- tws_binormal*averg_width*m_width*lengreal; vertexArray.append(pvx); pvx = MPoint(pw.x, pw.y, pw.z); vertexArray.append(pvx); pvx = MPoint(pw.x, pw.y, pw.z) + topright;//tws_binormal*averg_width*m_width*lengreal; vertexArray.append(pvx); uArray.append(0.0); vArray.append((float)j/NUMBENDSEG); uArray.append(0.5); vArray.append((float)j/NUMBENDSEG); uArray.append(1.0); vArray.append((float)j/NUMBENDSEG); } for(int j=0; j<NUMBENDSEG; j++) { polygonConnects.append(j*3 + numVertex); polygonConnects.append(j*3+3 + numVertex); polygonConnects.append(j*3+4 + numVertex); polygonConnects.append(j*3+1 + numVertex); polygonCounts.append(4); polygonConnects.append(j*3+1 + numVertex); polygonConnects.append(j*3+4 + numVertex); polygonConnects.append(j*3+5 + numVertex); polygonConnects.append(j*3+2 + numVertex); polygonCounts.append(4); polygonUVs.append(j*3 + numVertex); polygonUVs.append(j*3+3 + numVertex); polygonUVs.append(j*3+4 + numVertex); polygonUVs.append(j*3+1 + numVertex); polygonUVs.append(j*3+1 + numVertex); polygonUVs.append(j*3+4 + numVertex); polygonUVs.append(j*3+5 + numVertex); polygonUVs.append(j*3+2 + numVertex); } numVertex += (NUMBENDSEG+1)*3; numPolygon += NUMBENDSEG*2; } MFnMesh meshCreateFn; meshCreateFn.create( numVertex, numPolygon, vertexArray, polygonCounts, polygonConnects, outMeshData, &stat ); meshCreateFn.setUVs ( uArray, vArray ); meshCreateFn.assignUVs ( polygonCounts, polygonUVs ); return outMeshData; }
MStatus pointOnSubd::compute( const MPlug& plug, MDataBlock& data ) // // Description: // This method computes the value of the given output plug based // on the values of the input attributes. // // Arguments: // plug - the plug to compute // data - object that provides access to the attributes for this node // { MStatus returnStatus; // Check which output attribute we have been asked to compute. If this // node doesn't know how to compute it, we must return // MS::kUnknownParameter. // if( (plug == aPoint) || (plug == aNormal) || (plug == aPointX) || (plug == aNormalX) || (plug == aPointY) || (plug == aNormalY) || (plug == aPointZ) || (plug == aNormalZ) ) { // Get a handle to the input attribute that we will need for the // computation. If the value is being supplied via a connection // in the dependency graph, then this call will cause all upstream // connections to be evaluated so that the correct value is supplied. // do { MDataHandle subdHandle = data.inputValue( aSubd, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get subd\n" ); break; } MDataHandle faceFirstHandle = data.inputValue( aFaceFirst, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get face first\n" ); break; } MDataHandle faceSecondHandle = data.inputValue( aFaceSecond, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get face2\n" ); break; } MDataHandle uHandle = data.inputValue( aU, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get u\n" ); break; } MDataHandle vHandle = data.inputValue( aV, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get v\n" ); break; } MDataHandle relHandle = data.inputValue( aRelativeUV, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get relative UV\n" ); break; } // Read the input value from the handle. // MStatus stat; MObject subdValue = subdHandle.asSubdSurface(); MFnSubd subdFn( subdValue, &stat ); McheckErr(stat,"ERROR creating subd function set"); int faceFirstValue = faceFirstHandle.asLong(); int faceSecondValue = faceSecondHandle.asLong(); double uValue = uHandle.asDouble(); double vValue = vHandle.asDouble(); bool relUV = relHandle.asBool(); MPoint point; MVector normal; MUint64 polyId; stat = MFnSubdNames::fromSelectionIndices( polyId, faceFirstValue, faceSecondValue ); McheckErr(stat,"ERROR converting indices"); stat = subdFn.evaluatePositionAndNormal( polyId, uValue, vValue, relUV, point, normal ); normal.normalize(); McheckErr(stat,"ERROR evaluating the position and the normal"); // Get handles to the output attributes. This is similar to the // "inputValue" call above except that no dependency graph // computation will be done as a result of this call. // MDataHandle pointHandle = data.outputValue( aPoint ); pointHandle.set( point.x, point.y, point.z ); data.setClean(plug); MDataHandle normalHandle = data.outputValue( aNormal ); normalHandle.set( normal.x, normal.y, normal.z ); data.setClean(plug); } while( false ); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
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(); }
void CalculateBasisComponents(const MDoubleArray& weights, const BaryCoords& coords, const MIntArray& triangleVertices, const MPointArray& points, const MFloatVectorArray& normals, const MIntArray& sampleIds, double* alignedStorage, MPoint& origin, MVector& up, MVector& normal) { // Start with the recreated point and normal using the barycentric coordinates of the hit point. unsigned int hitIndex = weights.length()-1; #ifdef __AVX__ __m256d originV = Dot4<MPoint>(coords[0], coords[1], coords[2], 0.0, points[triangleVertices[0]], points[triangleVertices[1]], points[triangleVertices[2]], MPoint::origin); __m256d hitNormalV = Dot4<MVector>(coords[0], coords[1], coords[2], 0.0, normals[triangleVertices[0]], normals[triangleVertices[1]], normals[triangleVertices[2]], MVector::zero); __m256d hitWeightV = _mm256_set1_pd(weights[hitIndex]); // Create the barycentric point and normal. __m256d normalV = _mm256_mul_pd(hitNormalV, hitWeightV); // Then use the weighted adjacent data. for (unsigned int j = 0; j < hitIndex; j += 4) { __m256d tempNormal = Dot4<MVector>(weights[j], weights[j+1], weights[j+2], weights[j+3], normals[sampleIds[j]], normals[sampleIds[j+1]], normals[sampleIds[j+2]], normals[sampleIds[j+3]]); normalV = _mm256_add_pd(tempNormal, normalV); } _mm256_store_pd(alignedStorage, originV); origin.x = alignedStorage[0]; origin.y = alignedStorage[1]; origin.z = alignedStorage[2]; _mm256_store_pd(alignedStorage, normalV); normal.x = alignedStorage[0]; normal.y = alignedStorage[1]; normal.z = alignedStorage[2]; // Calculate the up vector const MPoint& pt1 = points[triangleVertices[0]]; const MPoint& pt2 = points[triangleVertices[1]]; __m256d p1 = _mm256_set_pd(pt1.w, pt1.z, pt1.y, pt1.x); __m256d p2 = _mm256_set_pd(pt2.w, pt2.z, pt2.y, pt2.x); p1 = _mm256_add_pd(p1, p2); __m256d half = _mm256_set_pd(0.5, 0.5, 0.5, 0.5); p1 = _mm256_mul_pd(p1, half); __m256d upV = _mm256_sub_pd(p1, originV); _mm256_store_pd(alignedStorage, upV); up.x = alignedStorage[0]; up.y = alignedStorage[1]; up.z = alignedStorage[2]; #else MVector hitNormal; // Create the barycentric point and normal. for (int i = 0; i < 3; ++i) { origin += points[triangleVertices[i]] * coords[i]; hitNormal += MVector(normals[triangleVertices[i]]) * coords[i]; } // Use crawl data to calculate normal normal = hitNormal * weights[hitIndex]; for (unsigned int j = 0; j < hitIndex; j++) { normal += MVector(normals[sampleIds[j]]) * weights[j]; } // Calculate the up vector // The triangle vertices are sorted by decreasing barycentric coordinates so the first two are // the two closest vertices in the triangle. up = ((points[triangleVertices[0]] + points[triangleVertices[1]]) * 0.5) - origin; #endif normal.normalize(); GetValidUp(weights, points, sampleIds, origin, normal, up); }
MStatus MG_nurbsRivet::compute(const MPlug& plug,MDataBlock& dataBlock) { //Get recompute value MDataHandle recomputeH = dataBlock.inputValue(recompute); bool recomputeV = recomputeH.asBool(); //input mesh MDataHandle inputNurbsH = dataBlock.inputValue(inputNurbSurface); MObject inputNurb = inputNurbsH.asNurbsSurfaceTransformed(); MMatrix offsetMatrixV = dataBlock.inputValue(offsetMatrix).asMatrix(); double U,V; MFnNurbsSurface nurbsFn ; nurbsFn.setObject(inputNurb); MStatus stat; if (recomputeV == true) { //input point MDataHandle inputPointH = dataBlock.inputValue(inputPoint); MPoint inputP = inputPointH.asVector(); MPoint closestP = nurbsFn.closestPoint(inputP,NULL,NULL,false,1e+99,MSpace::kObject); stat = nurbsFn.getParamAtPoint(closestP,U,V,MSpace::kObject); //Handle to U and V MDataHandle uValueH =dataBlock.outputValue(uValue); MDataHandle vValueH =dataBlock.outputValue(vValue); uValueH.set(float(U)); vValueH.set(float(V)); uValueH.setClean(); vValueH.setClean(); MDataHandle recomputeOutH = dataBlock.outputValue(recompute); } MDataHandle uH = dataBlock.inputValue(uValue); MDataHandle vH = dataBlock.inputValue(vValue); U = uH.asFloat(); V = vH.asFloat(); MPoint outPoint ; MVector uVec ; MVector vVec; MVector normal; //Get point stat = nurbsFn.getPointAtParam(U,V,outPoint,MSpace::kObject); //Since if getting both the U and V tangent was leading to some little rotation snapping //of the rivet I only used the U tangent and calculated the next one by dot product //of the normal and U tangent leading to a 100% stable rivet nurbsFn.getTangents(U,V,uVec,vVec,MSpace::kObject); uVec.normalize(); vVec.normalize(); MVector vVecCross; //Get normal normal = nurbsFn.normal(U,V,MSpace::kObject); normal.normalize(); vVecCross =(uVec^normal); //Build the maya matrix double myMatrix[4][4]={ { uVec.x, uVec.y , uVec.z, 0}, { normal[0], normal[1] , normal[2], 0}, {vVecCross.x, vVecCross.y , vVecCross.z, 0}, { outPoint[0], outPoint[1] , outPoint[2], 1}}; MMatrix rotMatrix (myMatrix); MMatrix offsetMatrixV2 = offsetMatrixV*rotMatrix; MTransformationMatrix matrixFn(offsetMatrixV2); double angles[3]; MTransformationMatrix::RotationOrder rotOrder; rotOrder =MTransformationMatrix::kXYZ; matrixFn.getRotation(angles,rotOrder,MSpace::kObject ); //get back radians value double radX,radY,radZ; radX=angles[0]; radY=angles[1]; radZ=angles[2]; //convert to degree double rotX,rotY,rotZ; rotX = radX*toDeg; rotY = radY*toDeg; rotZ = radZ*toDeg; MDataHandle outputRotateH = dataBlock.outputValue(outputRotate); outputRotateH.set3Double(rotX,rotY,rotZ); outputRotateH.setClean(); //let set the output matrix too MDataHandle outMH= dataBlock.outputValue(outputMatrix); outMH.set(rotMatrix); outMH.setClean(); MDataHandle outputH = dataBlock.outputValue(output); outputH.set(offsetMatrixV2[3][0],offsetMatrixV2[3][1],offsetMatrixV2[3][2]); outputH.setClean(); return MS::kSuccess; }
void IndigoRenderer::defineCamera() { std::shared_ptr<MayaScene> mayaScene = MayaTo::getWorldPtr()->worldScenePtr; std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr; for (auto mobj : mayaScene->camList) { std::shared_ptr<mtin_MayaObject> icam(std::static_pointer_cast<mtin_MayaObject>(mobj)); MFnCamera camFn(icam->dagPath); float lensRadius = 0.01; getFloat(MString("mtin_lensRadius"), camFn, lensRadius); bool autoFocus = false; getBool(MString("mtin_autoFocus"), camFn, autoFocus); MVector camUp = camFn.upDirection(MSpace::kWorld); MVector camView = camFn.viewDirection(MSpace::kWorld); MPoint camPos = camFn.eyePoint(MSpace::kWorld); MMatrix m = icam->transformMatrices[0]; MPoint pos, rot, scale; getMatrixComponents(m, pos, rot, scale); camPos *= renderGlobals->globalConversionMatrix; camUp *= renderGlobals->globalConversionMatrix; camView *= renderGlobals->globalConversionMatrix; camUp.normalize(); camView.normalize(); double focusDistance = camFn.focusDistance(); double horizFilmAperture = camFn.horizontalFilmAperture(); double focalLen = camFn.focalLength(); logger.debug(MString("Using camera: ") + icam->fullName); Indigo::SceneNodeCameraRef cam(new Indigo::SceneNodeCamera()); if( renderGlobals->doDof ) cam->lens_radius = lensRadius; else cam->lens_radius = lensRadius / 10000.0; //apertureRadius = $iFocalLength / ($FStop * 2.0); float exposureDuration = 0.333f; getFloat("mtin_exposureDuration", camFn, exposureDuration); cam->exposure_duration = exposureDuration; cam->focus_distance = focusDistance * scale.x; // scale by global matrix scale cam->lens_sensor_dist = focalLen/1000.0; cam->autofocus = autoFocus; //cam->lens_shift_right_distance = 0; //cam->lens_shift_up_distance = 0; cam->sensor_width = (horizFilmAperture * 2.54 * 10.0) / 1000.0; cam->camera_type = Indigo::SceneNodeCamera::CameraType_ThinLensPerspective; cam->forwards = Indigo::Vec3d(camView.x, camView.y, camView.z); cam->up = Indigo::Vec3d(camUp.x, camUp.y, camUp.z); cam->setPos(Indigo::Vec3d(camPos.x, camPos.y, camPos.z)); int appShape = 0; getEnum(MString("mtin_apertureShape"), camFn, appShape); if( appShape == 0) // circle cam->aperture_shape = new Indigo::ApertureCircular(); if( appShape == 1) // generated { int numBlades = 5; float startAngle = 0.0f; float offset = 0.0f; float radius = 0.0f; getInt("mtin_numBlades", camFn, numBlades); getFloat("mtin_startAngle", camFn, startAngle); getFloat("mtin_bladeOffset", camFn, offset); getFloat("mtin_bladeCurvatureRadius", camFn, radius); cam->aperture_shape = new Indigo::ApertureGenerated(numBlades, offset, radius, startAngle); } if( appShape == 2) // image { MString fileName; getString(MString("mtin_appFile"), camFn, fileName); if( fileName.length() > 4) cam->aperture_shape = new Indigo::ApertureImage(fileName.asChar()); } sceneRootRef->addChildNode(cam); } }
void MG_vectorGL::drawArrow( MVector vec , MVector upVec , double arrowSizeV , MPoint startPointV ) { vec.normalize(); upVec.normalize(); double tipX , tipY , tipZ, corner1X ,corner1Y ,corner1Z , corner2X ,corner2Y ,corner2Z , corner3X ,corner3Y ,corner3Z , corner4X ,corner4Y ,corner4Z ; double dot = vec*upVec; if (dot >= 0.99 ) { tipX=(0.0)+startPointV.x; tipY=(1.0*arrowSizeV)+startPointV.y; tipZ=(0.0)+startPointV.z; corner1Y=(0.9*arrowSizeV)+startPointV.y; corner1X=(0.05*arrowSizeV)+startPointV.x ; corner1Z=(-0.05*arrowSizeV)+startPointV.z; corner2Y=(0.9*arrowSizeV)+startPointV.y; corner2X=(0.05*arrowSizeV)+startPointV.x; corner2Z=(0.05*arrowSizeV)+startPointV.z; corner3Y=(0.9*arrowSizeV)+startPointV.y; corner3X=(-0.05*arrowSizeV)+startPointV.x; corner3Z=(0.05*arrowSizeV)+startPointV.z; corner4Y=(0.9*arrowSizeV)+startPointV.y; corner4X=(-0.05*arrowSizeV)+startPointV.x; corner4Z=(-0.05*arrowSizeV)+startPointV.z; } else if (dot <= -0.99) { tipX=(0.0)+startPointV.x; tipY=(1.0*arrowSizeV*-1)+startPointV.y; tipZ=(0.0)+startPointV.z; corner1Y=(0.9*arrowSizeV*-1)+startPointV.y; corner1X=(0.05*arrowSizeV)+startPointV.x ; corner1Z=(-0.05*arrowSizeV)+startPointV.z; corner2Y=(0.9*arrowSizeV*-1)+startPointV.y; corner2X=(0.05*arrowSizeV)+startPointV.x; corner2Z=(0.05*arrowSizeV)+startPointV.z; corner3Y=(0.9*arrowSizeV*-1)+startPointV.y; corner3X=(-0.05*arrowSizeV)+startPointV.x; corner3Z=(0.05*arrowSizeV)+startPointV.z; corner4Y=(0.9*arrowSizeV*-1)+startPointV.y; corner4X=(-0.05*arrowSizeV)+startPointV.x; corner4Z=(-0.05*arrowSizeV)+startPointV.z; } else { MVector cross1Pos = vec^upVec; cross1Pos.normalize(); MVector cross2Pos = cross1Pos^vec; MVector vecScaled = vec*0.9; MVector corner1 = (((cross1Pos*0.07)+vecScaled)*arrowSizeV)+startPointV; MVector corner2 = (((cross2Pos*0.07)+vecScaled)*arrowSizeV)+startPointV; MVector corner3 = (((cross1Pos*0.07*-1)+vecScaled)*arrowSizeV)+startPointV; MVector corner4 = (((cross2Pos*0.07*-1)+vecScaled)*arrowSizeV)+startPointV; corner1X = corner1.x; corner1Y = corner1.y; corner1Z = corner1.z; corner2X = corner2.x; corner2Y = corner2.y; corner2Z = corner2.z; corner3X = corner3.x; corner3Y = corner3.y; corner3Z = corner3.z; corner4X = corner4.x; corner4Y = corner4.y; corner4Z = corner4.z; tipX = (vec.x*arrowSizeV) +startPointV.x; tipY = (vec.y*arrowSizeV)+startPointV.y; tipZ = (vec.z*arrowSizeV)+startPointV.z; } glBegin(GL_LINES); //draw the reader glVertex3d(0+startPointV.x,0+startPointV.y,0+startPointV.z); glVertex3d(tipX,tipY,tipZ); glEnd(); glBegin(GL_TRIANGLES); glVertex3d(corner1X,corner1Y,corner1Z); glVertex3d(corner2X,corner2Y,corner2Z); glVertex3d(tipX,tipY,tipZ); glEnd(); glBegin(GL_TRIANGLES); glVertex3d(corner3X,corner3Y,corner3Z); glVertex3d(corner2X,corner2Y,corner2Z); glVertex3d(tipX,tipY,tipZ); glEnd(); glBegin(GL_TRIANGLES); glVertex3d(corner3X,corner3Y,corner3Z); glVertex3d(corner4X,corner4Y,corner4Z); glVertex3d(tipX,tipY,tipZ); glEnd(); glBegin(GL_TRIANGLES); glBegin(GL_TRIANGLES); glVertex3d(corner1X,corner1Y,corner1Z); glVertex3d(corner4X,corner4Y,corner4Z); glVertex3d(tipX,tipY,tipZ); glEnd(); }
MStatus sgCurveEditBrush_context::editCurve( MDagPath dagPathCurve, int beforeX, int beforeY, int currentX, int currentY, float radius, const MDoubleArray& dArrLength, MPointArray &points ) { MStatus status; if( radius < 0 ) return MS::kSuccess; MDagPath dagPathCam; M3dView view = M3dView::active3dView( &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); view.getCamera( dagPathCam ); MPoint camPos = dagPathCam.inclusiveMatrix()[3]; MVector vCamUp = dagPathCam.inclusiveMatrix()[1]; vCamUp.normalize(); radius *= .05; MPoint nearClipBefore; MPoint farClipBefore; view.viewToWorld( beforeX, beforeY, nearClipBefore, farClipBefore ); MVector rayBefore = nearClipBefore - camPos; rayBefore.normalize(); rayBefore *= 20; MPoint posBefore = rayBefore + camPos; MPoint nearClipCurrent; MPoint farClipCurrent; view.viewToWorld( currentX, currentY, nearClipCurrent, farClipCurrent ); MVector rayCurrent = nearClipCurrent - camPos; rayCurrent.normalize(); rayCurrent *= 20; MPoint posCurrent = rayCurrent + camPos; MVector vMove = posCurrent - posBefore; MMatrix mtxCurve = dagPathCurve.inclusiveMatrix(); MFnNurbsCurve fnCurve( dagPathCurve ); fnCurve.getCVs( points ); for( int i=0; i< points.length(); i++ ) { points[i] *= mtxCurve; } for( int i=1; i< points.length(); i++ ) { MPoint cuPoint = points[i]; MVector vPoint = cuPoint - camPos; MVector projV = ( vPoint * rayBefore )/( pow( rayBefore.length(), 2 ) )* rayBefore; MVector vertical = vPoint - projV; float radiusForPoint = vertical.length() / projV.length(); if( radius < radiusForPoint ) continue; MPoint parentPoint = points[i-1]; MVector vCurveDirection = cuPoint - parentPoint; double vDirLength = vCurveDirection.length(); MVector vEditDirection = vCurveDirection + vMove/rayBefore.length()*projV.length(); double dotEdit = vCurveDirection.normal() * vEditDirection.normal(); if( dotEdit < 0 ) continue; vEditDirection = vEditDirection * dotEdit + vCurveDirection*( 1-dotEdit ); MVector vEditLength = vEditDirection / vEditDirection.length() * vCurveDirection.length(); MVector vEdit = (vEditLength - vCurveDirection) * pow((double)(1-radiusForPoint/radius), 1 ); points[i] += vEdit; for( int j=i+1; j< points.length(); j++ ) { MPoint beforePoint = points[j]; MPoint pPoint = points[j-1]; MPoint beforePPoint = pPoint - vEdit; MVector vBefore = points[j] - beforePPoint; MVector vAfter = points[j] - pPoint; MVector vCurrent = vAfter.normal() * dArrLength[j]; points[j] = vCurrent + pPoint; vEdit = points[j] - beforePoint; } } MMatrix invMtxCurve = mtxCurve.inverse(); for( int i=0; i< points.length(); i++ ) { points[i] *= invMtxCurve; } fnCurve.setCVs( points ); fnCurve.updateCurve(); return MS::kSuccess; }
void gpuCacheIsectUtil::getClosestPointToRayOnLine(const MPoint& vertex1, const MPoint& vertex2, const MPoint& raySource, const MVector& rayDirection, MPoint& closestPoint, double& percent){ MPoint clsPoint; MVector edgeDir = vertex2 - vertex1; double len = edgeDir.length(); if(len < 0.0000001 ) { percent = 0.0; closestPoint = vertex1; return; } edgeDir.normalize(); //if line is parallel to ray double dotPrd = fabs(edgeDir * rayDirection); if(dotPrd > 0.9999){ percent = 0.0; closestPoint = vertex1; return; } // Vector connecting two closest points. // MVector crossProd = edgeDir ^ rayDirection; // Normal to the plane defined by that vector and the 'otherLine'. // MVector planeNormal = rayDirection ^ crossProd; //intersectionPlane is raySource,planeNormal double t; if(intersectPlane(raySource, planeNormal, vertex1,edgeDir,t)){ clsPoint = vertex1 + t * edgeDir; // Find percent, where // vertex1 + percent * (edgeDir) == closestPoint // percent = edgeDir * (clsPoint - vertex1) / len; // The closest point may not be on the segment. Find the closest // point on the segment using t. // if (percent < 0) { closestPoint = vertex1; percent = 0.0; } else if (percent > 1.0) { closestPoint = vertex2; percent = 1.0; } else { closestPoint = clsPoint; } } else { closestPoint = vertex1; percent = 0.0; } }