void VRayCamera::getTM(TimeValue t, INode *node, ViewExp *vpt, Matrix3 &tm) {
  tm=node->GetObjectTM(t);

  AffineParts ap;
  decomp_affine(tm, &ap);
  tm.IdentityMatrix();
  tm.SetRotate(ap.q);
  tm.SetTrans(ap.t);

  float scaleFactor=vpt->NonScalingObjectSize()*vpt->GetVPWorldWidth(tm.GetTrans())/360.0f;
  tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor));
}
Esempio n. 2
0
// Luna task 748T
void ConvertPathToFrenets (Spline3D *pSpline, Matrix3 & relativeTransform, Tab<Matrix3> & tFrenets,
						   int numSegs, bool align, float rotateAroundZ) {
	// Given a path, a sequence of points in 3-space, create transforms
	// for putting a cross-section around each of those points, loft-style.

	// bezShape is provided by user, tFrenets contains output, numSegs is one less than the number of transforms requested.

	// Strategy: The Z-axis is mapped along the path, and the X and Y axes 
	// are chosen in a well-defined manner to get an orthonormal basis.

	int i;

	if (numSegs < 1) return;
	tFrenets.SetCount (numSegs+1);

	int numIntervals = pSpline->Closed() ? numSegs+1 : numSegs;
	float denominator = float(numIntervals);
	Point3 xDir, yDir, zDir, location, tangent, axis;
	float position, sine, cosine, theta;
	Matrix3 rotation;

	// Find initial x,y directions:
	location = relativeTransform * pSpline->InterpCurve3D (0.0f);
	tangent = relativeTransform.VectorTransform (pSpline->TangentCurve3D (0.0f));
	Point3 lastTangent = tangent;

	Matrix3 inverseBasisOfSpline(1);
	if (align) {
		theBasisFinder.BasisFromZDir (tangent, xDir, yDir);
		if (rotateAroundZ) {
			Matrix3 rotator(1);
			rotator.SetRotate (AngAxis (tangent, rotateAroundZ));
			xDir = xDir * rotator;
			yDir = yDir * rotator;
		}
		Matrix3 basisOfSpline(1);
		basisOfSpline.SetRow (0, xDir);
		basisOfSpline.SetRow (1, yDir);
		basisOfSpline.SetRow (2, tangent);
		basisOfSpline.SetTrans (location);
		inverseBasisOfSpline = Inverse (basisOfSpline);
		lastTangent = Point3(0,0,1);
	} else {
		inverseBasisOfSpline.SetRow (3, -location);
	}

	// Make relative transform take the spline from its own object space to our object space,
	// and from there into the space defined by its origin and initial direction:
	relativeTransform = relativeTransform * inverseBasisOfSpline;
	// (Note left-to-right evaluation order: Given matrices A,B, point x, x(AB) = (xA)B

	// The first transform is necessarily the identity:
	tFrenets[0].IdentityMatrix ();

	// Set up xDir, yDir, zDir to match our first-point basis:
	xDir = Point3 (1,0,0);
	yDir = Point3 (0,1,0);
	zDir = Point3 (0,0,1);

	for (i=1; i<=numIntervals; i++) {
		position = float(i) / denominator;
		location = relativeTransform * pSpline->InterpCurve3D (position);
		tangent = relativeTransform.VectorTransform (pSpline->TangentCurve3D (position));

		// This is the procedure we follow at each step in the path: find the
		// orthonormal basis with the right orientation, then compose with
		// the translation putting the origin at the path-point.

		// As we proceed along the path, we apply minimal rotations to
		// our original basis to keep the Z-axis tangent to the curve.
		// The X and Y axes follow in a natural manner.

		// xDir, yDir, zDir still have their values from last time...
		// Create a rotation matrix which maps the last tangent onto the current tangent:
		axis = lastTangent ^ tangent;	// gives axis, scaled by sine of angle.
		sine = FLength(axis);	// positive - keeps angle value in (0,PI) range.
		cosine = DotProd (lastTangent, tangent);	// Gives cosine of angle.
		theta = atan2f (sine, cosine);
		rotation.SetRotate (AngAxis (Normalize(axis), theta));
		xDir = Normalize (rotation * xDir);
		yDir = Normalize (rotation * yDir);
		zDir = Normalize (rotation * zDir);
		lastTangent = tangent;

		if (i<=numSegs) {
			tFrenets[i].IdentityMatrix ();
			tFrenets[i].SetRow (0, xDir);
			tFrenets[i].SetRow (1, yDir);
			tFrenets[i].SetRow (2, zDir);
			tFrenets[i].SetTrans (location);
		}
	}

	/* following code not needed for now - treating all splines as open.
	if (!pSpline->Closed ()) return;

	// If we have a closed loop, our procedure may result in X,Y vectors
	// that are twisted severely between the first and last point.
	// Here we correct for that by pre-transforming each frenet transform
	// by a small rotation around the Z-axis.  (The last pass through the above
	// loop should give the final twist: the initial and final Z-axis directions
	// are the same, and the difference between the initial and final X-axis
	// directions is the total twist along the spline.)

	// Now we measure the difference between our original and final x-vectors:
	axis = originalXDir ^ xDir;
	sine = FLength (axis);
	cosine = DotProd (originalXDir, xDir);
	theta = atan2f (sine, cosine);
	for (i=1; i<=numSegs; i++) {
		rotation.SetRotate (AngAxis (Normalize(axis), -theta/denominator));
		tFrenets[i] = rotation * tFrenets[i];
	}
*/	
}
Esempio n. 3
0
void CExportNel::addSkeletonBindPos (INode& skinedNode, mapBoneBindPos& boneBindPos)
{
	// Return success
	uint ok=NoError;

	// Get the skin modifier
	Modifier* skin=getModifier (&skinedNode, SKIN_CLASS_ID);

	// Found it ?
	if (skin)
	{
		// Get a com_skin2 interface
		ISkin *comSkinInterface=(ISkin*)skin->GetInterface (SKIN_INTERFACE);

		// Should been controled with isSkin before.
		nlassert (comSkinInterface);

		// Found com_skin2 ?
		if (comSkinInterface)
		{
			// Get local data
			ISkinContextData *localData=comSkinInterface->GetContextInterface(&skinedNode);

			// Should been controled with isSkin before.
			nlassert (localData);

			// Found ?
			if (localData)
			{
				// Check same vertices count
				uint vertCount=localData->GetNumPoints();

				// For each vertex
				for (uint vert=0; vert<vertCount; vert++)
				{
					// Get bones count for this vertex
					uint boneCount=localData->GetNumAssignedBones (vert);

					// For each bones
					for (uint bone=0; bone<boneCount; bone++)
					{
						// Get the bone id
						int boneId=localData->GetAssignedBone(vert, bone);

						// Get bone INode*
						INode *boneNode=comSkinInterface->GetBone(boneId);

						// Get the bind matrix of the bone
						Matrix3 bindPos;
						comSkinInterface->GetBoneInitTM(boneNode, bindPos);

						// Add an entry inthe map
						boneBindPos.insert (mapBoneBindPos::value_type (boneNode, bindPos));
					}
				}
			}

			// Release the interface
			skin->ReleaseInterface (SKIN_INTERFACE, comSkinInterface);
		}
	}
	else
	{
		// Get the skin modifier
		Modifier* skin=getModifier (&skinedNode, PHYSIQUE_CLASS_ID);

		// Should been controled with isSkin before.
		nlassert (skin);

		// Found it ?
		if (skin)
		{
			// Get a com_skin2 interface
			IPhysiqueExport *physiqueInterface=(IPhysiqueExport *)skin->GetInterface (I_PHYINTERFACE);

			// Should been controled with isSkin before.
			nlassert (physiqueInterface);

			// Found com_skin2 ?
			if (physiqueInterface)
			{
				// Get local data
				IPhyContextExport *localData=physiqueInterface->GetContextInterface(&skinedNode);

				// Should been controled with isSkin before.
				nlassert (localData);

				// Found ?
				if (localData)
				{
					// Use rigid export
					localData->ConvertToRigid (TRUE);

					// Allow blending
					localData->AllowBlending (TRUE);

					// Check same vertices count
					uint vertCount=localData->GetNumberVertices();

					// For each vertex
					for (uint vert=0; vert<vertCount; vert++)
					{
						if (vert==111)
							int toto=0;
						// Get a vertex interface
						IPhyVertexExport *vertexInterface=localData->GetVertexInterface (vert);

						// Check if it is a rigid vertex or a blended vertex
						int type=vertexInterface->GetVertexType ();
						if (type==RIGID_TYPE)
						{
							// this is a rigid vertex
							IPhyRigidVertex			*rigidInterface=(IPhyRigidVertex*)vertexInterface;

							// Get bone INode*
							INode *bone=rigidInterface->GetNode();

							// Get the bind matrix of the bone
							Matrix3 bindPos;
							int res=physiqueInterface->GetInitNodeTM (bone, bindPos);
							nlassert (res==MATRIX_RETURNED);

							// Add an entry inthe map
							if (boneBindPos.insert (mapBoneBindPos::value_type (bone, bindPos)).second)
							{
#ifdef NL_DEBUG
								// *** Debug info

								// Bone name
								std::string boneName=getName (*bone);

								// Local matrix
								Matrix3 nodeTM;
								nodeTM=bone->GetNodeTM (0);

								// Offset matrix
								Matrix3 offsetScaleTM (TRUE);
								Matrix3 offsetRotTM (TRUE);
								Matrix3 offsetPosTM (TRUE);
								ApplyScaling (offsetScaleTM, bone->GetObjOffsetScale ());
								offsetRotTM.SetRotate (bone->GetObjOffsetRot ());
								offsetPosTM.SetTrans (bone->GetObjOffsetPos ());
								Matrix3 offsetTM = offsetScaleTM * offsetRotTM * offsetPosTM;

								// Local + offset matrix
								Matrix3 nodeOffsetTM = offsetTM * nodeTM;

								// Init TM
								Matrix3 initTM;
								int res=physiqueInterface->GetInitNodeTM (bone, initTM);
								nlassert (res==MATRIX_RETURNED);

								// invert
								initTM.Invert();
								Matrix3 compNode=nodeTM*initTM;
								Matrix3 compOffsetNode=nodeOffsetTM*initTM;
								Matrix3 compOffsetNode2=nodeOffsetTM*initTM;
#endif // NL_DEBUG
							}
						}
						else
						{
							// It must be a blendable vertex
							nlassert (type==RIGID_BLENDED_TYPE);
							IPhyBlendedRigidVertex	*blendedInterface=(IPhyBlendedRigidVertex*)vertexInterface;

							// For each bones
							uint boneIndex;
							uint count=(uint)blendedInterface->GetNumberNodes ();
							for (boneIndex=0; boneIndex<count; boneIndex++)
							{
								// Get the bone pointer
								INode *bone = blendedInterface->GetNode(boneIndex);

								if (bone == NULL)
								{
									nlwarning("bone == NULL; boneIndex = %i / %i", boneIndex, count);
								}
								else
								{
									// Get the bind matrix of the bone
									Matrix3 bindPos;
									int res = physiqueInterface->GetInitNodeTM (bone, bindPos);

									if (res != MATRIX_RETURNED)
									{
										nlwarning("res != MATRIX_RETURNED; res = %i; boneIndex = %i / %i", res, boneIndex, count);
										nlwarning("bone = %i", (uint32)(void *)bone);
										std::string boneName = getName (*bone);
										nlwarning("boneName = %s", boneName.c_str());
										nlassert(false);
									}

									// Add an entry inthe map
									if (boneBindPos.insert (mapBoneBindPos::value_type (bone, bindPos)).second)
									{
	#ifdef NL_DEBUG
										// *** Debug info

										// Bone name
										std::string boneName=getName (*bone);

										// Local matrix
										Matrix3 nodeTM;
										nodeTM=bone->GetNodeTM (0);

										// Offset matrix
										Matrix3 offsetScaleTM (TRUE);
										Matrix3 offsetRotTM (TRUE);
										Matrix3 offsetPosTM (TRUE);
										ApplyScaling (offsetScaleTM, bone->GetObjOffsetScale ());
										offsetRotTM.SetRotate (bone->GetObjOffsetRot ());
										offsetPosTM.SetTrans (bone->GetObjOffsetPos ());
										Matrix3 offsetTM = offsetScaleTM * offsetRotTM * offsetPosTM;

										// Local + offset matrix
										Matrix3 nodeOffsetTM = offsetTM * nodeTM;

										// Init TM
										Matrix3 initTM;
										int res=physiqueInterface->GetInitNodeTM (bone, initTM);
										nlassert (res==MATRIX_RETURNED);

										// invert
										initTM.Invert();
										Matrix3 compNode=nodeTM*initTM;
										Matrix3 compOffsetNode=nodeOffsetTM*initTM;
										Matrix3 compOffsetNode2=nodeOffsetTM*initTM;
#endif // NL_DEBUG
									}
								}
							}
						}
					
						// Release vertex interfaces
						localData->ReleaseVertexInterface (vertexInterface);
					}

					// Release locaData interface
					physiqueInterface->ReleaseContextInterface (localData);
				}

				// Release the interface
				skin->ReleaseInterface (SKIN_INTERFACE, physiqueInterface);
			}
		}
	}
}