Beispiel #1
0
bool MannequinMoveManipulator::intersectManip(MPxManipulatorNode* manip) const {
  M3dView view = M3dView::active3dView();

  float size = _manipScale * MFnManip3D::globalSize();
  MPoint xEnd = _origin + (_x * size);
  MPoint yEnd = _origin + (_y * size);
  MPoint zEnd = _origin + (_z * size);

  short mx, my;
  manip->mousePosition(mx, my);

  short ox, oy, xx, xy, yx, yy, zx, zy;
  view.worldToView(_origin, ox, oy);
  view.worldToView(xEnd, xx, xy);
  view.worldToView(yEnd, yx, yy);
  view.worldToView(zEnd, zx, zy);

  // Calculate approximate handle size in view space.
  float viewLength = 0.0f;
  viewLength = std::max(viewLength,
    sqrtf(pow(float(xx) - float(ox), 2) + pow(float(xy) - float(oy), 2)));
  viewLength = std::max(viewLength,
    sqrtf(pow(float(yx) - float(ox), 2) + pow(float(yy) - float(oy), 2)));
  viewLength = std::max(viewLength,
    sqrtf(pow(float(zx) - float(ox), 2) + pow(float(zy) - float(oy), 2)));

  float handleSize = MFnManip3D::handleSize() / 100.0f; // Probably on [0, 100].
  float handleHeight = viewLength * handleSize * 0.5f;
  float handleRadius = std::max(handleHeight * 0.3f, 4.0f);
  // Note: slightly exaggerated; normally handleHeight * 0.25f.

  // Determine if we're in range to any of the lines.
  float curDist, t;

  curDist = Util::distanceToLine(ox, oy, xx, xy, mx, my, &t);
  if (curDist < handleRadius && t >= 0.0f && t <= 1.0f) {
    return true;
  }

  curDist = Util::distanceToLine(ox, oy, yx, yy, mx, my, &t);
  if (curDist < handleRadius && t >= 0.0f && t <= 1.0f) {
    return true;
  }

  curDist = Util::distanceToLine(ox, oy, zx, zy, mx, my, &t);
  if (curDist < handleRadius && t >= 0.0f && t <= 1.0f) {
    return true;
  }

  return false;
}
Beispiel #2
0
MStatus MannequinMoveManipulator::doPress(M3dView& view) {
  getPointValue(_translateIndex, false, _opValueBegin);

  GLuint activeAxis;
  glActiveName(activeAxis);

  if (activeAxis == _glPickableItem + 0) {
    _opAxis = _x;
    _opAxisIndex = 0;
  } else if (activeAxis == _glPickableItem + 1) {
    _opAxis = _y;
    _opAxisIndex = 1;
  } else if (activeAxis == _glPickableItem + 2) {
    _opAxis = _z;
    _opAxisIndex = 2;
  } else {
    _opAxis = MVector::zero;
    _opValid = false;
    return MS::kUnknownParameter;
  }

  _opOrigin = _origin;

  // Determine the translation "plane"; it is orthogonal to the axis and faces
  // the view as best as possible.
  short originX, originY;
  view.worldToView(_opOrigin, originX, originY);

  MPoint rayNear;
  MVector dirToOrigin;
  view.viewToWorld(originX, originY, rayNear, dirToOrigin);

  MVector dirInPlane = dirToOrigin ^ _opAxis;
  _opPlaneNormal = dirInPlane ^ _opAxis;

  // Determine where the current mouse ray hits the plane.
  MPoint rayOrigin;
  MVector rayDirection;
  mouseRayWorld(rayOrigin, rayDirection);

  MPoint isect;
  bool didIsect = Util::rayPlaneIntersection(rayOrigin,
                                             rayDirection,
                                             _opOrigin,
                                             _opPlaneNormal,
                                             &isect);

  if (!didIsect) {
    _opValid = false;
    return MS::kUnknownParameter;
  }

  _opHitBegin = isect;
  _opValid = true;

  // We need to calculate the handle directions in parent space. This is
  // because the handle positions align with the child pivot rotation, so they
  // DO NOT correspond to the child's X, Y, and Z-position, which are
  // indicated in terms of the parent's coordinate space.
  MMatrix parentInverse = _parentXform.asMatrixInverse();
  _xInParentSpace = _x * parentInverse;
  _yInParentSpace = _y * parentInverse;
  _zInParentSpace = _z * parentInverse;

  return MS::kSuccess;
}
Beispiel #3
0
MStatus lassoTool::doRelease( MEvent & /*event*/ )
// Selects objects within the lasso
{
	MStatus							stat;
	MSelectionList					incomingList, boundingBoxList, newList;

	if (!firstDraw) {
		// Redraw the lasso to clear it.
		view.beginXorDrawing(true, true, 1.0f, M3dView::kStippleDashed);
		draw_lasso();
		view.endXorDrawing();
	}

	// We have a non-zero sized lasso.  Close the lasso, and sort
	// all the points on it.
	append_lasso(lasso[0].h, lasso[0].v);
	qsort( &(lasso[0]), num_points, sizeof( coord  ),
		(int (*)(const void *, const void *))xycompare);

	// Save the state of the current selections.  The "selectFromSceen"
	// below will alter the active list, and we have to be able to put
	// it back.
	MGlobal::getActiveSelectionList(incomingList);

	// As a first approximation to the lasso, select all components with
	// the bounding box that just contains the lasso.
	MGlobal::selectFromScreen( min.h, min.v, max.h, max.v,
							   MGlobal::kReplaceList );

	// Get the list of selected items from within the bounding box
	// and create a iterator for them.
	MGlobal::getActiveSelectionList(boundingBoxList);

	// Restore the active selection list to what it was before we
	// the "selectFromScreen"
	MGlobal::setActiveSelectionList(incomingList, MGlobal::kReplaceList);

	// Iterate over the objects within the bounding box, extract the
	// ones that are within the lasso, and add those to newList.
	MItSelectionList iter(boundingBoxList);
	newList.clear();

	bool	foundEntireObjects = false;
	bool	foundComponents = false;

	for ( ; !iter.isDone(); iter.next() ) {
		MDagPath	dagPath;
		MObject		component;
		MPoint		point;
		coord		pt;
		MObject     singleComponent;

		iter.getDagPath( dagPath, component );

		if (component.isNull()) {
			foundEntireObjects = true;
			continue; // not a component
		}

		foundComponents = true;

		switch (component.apiType()) {
		case MFn::kCurveCVComponent:
			{
				MItCurveCV curveCVIter( dagPath, component, &stat );
				for ( ; !curveCVIter.isDone(); curveCVIter.next() ) {
					point = curveCVIter.position(MSpace::kWorld, &stat );
					view.worldToView( point, pt.h, pt.v, &stat );
					if (!stat) {
						stat.perror("Could not get position");
						continue;
					}
					if ( point_in_lasso( pt ) ) {
						singleComponent = curveCVIter.cv();
						newList.add (dagPath, singleComponent);
					}
				}
				break;
			}

		case MFn::kSurfaceCVComponent:
			{
				MItSurfaceCV surfCVIter( dagPath, component, true, &stat );
				for ( ; !surfCVIter.isDone(); surfCVIter.next() ) {
					point = surfCVIter.position(MSpace::kWorld, &stat );
					view.worldToView( point, pt.h, pt.v, &stat );
					if (!stat) {
						stat.perror("Could not get position");
						continue;
					}
					if ( point_in_lasso( pt ) ) {
						singleComponent = surfCVIter.cv();
						newList.add (dagPath, singleComponent);
					}
				}
				break;
			}

		case MFn::kMeshVertComponent:
			{
				MItMeshVertex vertexIter( dagPath, component, &stat );
				for ( ; !vertexIter.isDone(); vertexIter.next() ) {
					point = vertexIter.position(MSpace::kWorld, &stat );
					view.worldToView( point, pt.h, pt.v, &stat );
					if (!stat) {
						stat.perror("Could not get position");
						continue;
					}
					if ( point_in_lasso( pt ) ) {
						singleComponent = vertexIter.vertex();
						newList.add (dagPath, singleComponent);
					}
				}
				break;
			}

		case MFn::kMeshEdgeComponent:
			{
				MItMeshEdge edgeIter( dagPath, component, &stat );
				for ( ; !edgeIter.isDone(); edgeIter.next() ) {
					point = edgeIter.center(MSpace::kWorld, &stat );
					view.worldToView( point, pt.h, pt.v, &stat );
					if (!stat) {
						stat.perror("Could not get position");
						continue;
					}
					if ( point_in_lasso( pt ) ) {
						singleComponent = edgeIter.edge();
						newList.add (dagPath, singleComponent);
					}
				}
				break;
			}

		case MFn::kMeshPolygonComponent:
			{
				MItMeshPolygon polygonIter( dagPath, component, &stat );
				for ( ; !polygonIter.isDone(); polygonIter.next() ) {
					point = polygonIter.center(MSpace::kWorld, &stat );
					view.worldToView( point, pt.h, pt.v, &stat );
					if (!stat) {
						stat.perror("Could not get position");
						continue;
					}
					if ( point_in_lasso( pt ) ) {
						singleComponent = polygonIter.polygon();
						newList.add (dagPath, singleComponent);
					}
				}
				break;
			}

		default:
#ifdef DEBUG
			cerr << "Selected unsupported type: (" << component.apiType()
				 << "): " << component.apiTypeStr() << endl;
#endif /* DEBUG */
			continue;
		}
	}

	// Warn user if zie is trying to select objects rather than components.
	if (foundEntireObjects && !foundComponents) {
		MGlobal::displayWarning("lassoTool can only select components, not entire objects.");
	}

	// Update the selection list as indicated by the modifier keys.
	MGlobal::selectCommand(newList, listAdjustment);

	// Free the memory that held our lasso points.
	free(lasso);
	lasso = (coord*) 0;
	maxSize = 0;
	num_points = 0;
 
	return MS::kSuccess;
}