Пример #1
0
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;
}
Пример #2
0
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;
			}
		}
	}
}
Пример #3
0
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();

}
Пример #4
0
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;

}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
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;

}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;


}
Пример #12
0
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;
  }
}
Пример #13
0
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 );
}
Пример #14
0
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;
}
Пример #15
0
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);
    }
}
Пример #16
0
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;
	}
Пример #17
0
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);


}
Пример #18
0
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);
}
Пример #19
0
// 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;
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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();
}
Пример #25
0
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);
}
Пример #26
0
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;
	}
Пример #27
0
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);
	}
}
Пример #28
0
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;
}
Пример #30
0
	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;
		}
	}