예제 #1
0
void OpenSimContext::setLocation(PathPoint& mp, int i, double d) {
    mp.setLocation(*_configState, i, d);
  _configState->invalidateAll(SimTK::Stage::Position);
  _model->getMultibodySystem().realize(*_configState, SimTK::Stage::Position);
  mp.getPath()->updateGeometry(*_configState);
    return;
}
예제 #2
0
/*
 * Add a new path point, with default location, to the path.
 *
 * @param aIndex The position in the pathPointSet to put the new point in.
 * @param aBody The body to attach the point to.
 * @return Pointer to the newly created path point.
 */
PathPoint* GeometryPath::
addPathPoint(const SimTK::State& s, int aIndex, PhysicalFrame& aBody)
{
    PathPoint* newPoint = new PathPoint();
    newPoint->setBody(aBody);
    Vec3& location = newPoint->getLocation();
    placeNewPathPoint(s, location, aIndex, aBody);
    upd_PathPointSet().insert(aIndex, newPoint);

    // Rename the path points starting at this new one.
    namePathPoints(aIndex);

    // Update start point and end point in the wrap instances so that they
    // refer to the same path points they did before the new point
    // was added. These indices are 1-based.
    aIndex++;
    for (int i=0; i<get_PathWrapSet().getSize(); i++) {
        int startPoint = get_PathWrapSet().get(i).getStartPoint();
        int endPoint = get_PathWrapSet().get(i).getEndPoint();
        if (startPoint != -1 && aIndex <= startPoint)
            get_PathWrapSet().get(i).setStartPoint(s,startPoint + 1);
        if (endPoint != -1 && aIndex <= endPoint)
            get_PathWrapSet().get(i).setEndPoint(s,endPoint + 1);
    }

    return newPoint;
}
예제 #3
0
/**
 * Calculate the wrapping of one path segment over one wrap object.
 *
 * @param aPoint1 The first patth point
 * @param aPoint2 The second path point
 * @param aPathWrap An object holding the parameters for this path/wrap-object pairing
 * @param aWrapResult The result of the wrapping (tangent points, etc.)
 * @return The status, as a WrapAction enum
 */
int WrapObject::wrapPathSegment(const SimTK::State& s, PathPoint& aPoint1, PathPoint& aPoint2,
										  const PathWrap& aPathWrap, WrapResult& aWrapResult) const
{
   int return_code = noWrap;
	bool p_flag;
	Vec3 pt1(0.0);
	Vec3 pt2(0.0);

	// Convert the path points from the frames of the bodies they are attached
	// to to the frame of the wrap object's body
	_model->getSimbodyEngine().transformPosition(s, aPoint1.getBody(), aPoint1.getLocation(), getBody(), pt1);

	_model->getSimbodyEngine().transformPosition(s, aPoint2.getBody(), aPoint2.getLocation(), getBody(), pt2);

	// Convert the path points from the frame of the wrap object's body
	// into the frame of the wrap object
	pt1 = _pose.shiftBaseStationToFrame(pt1);
	pt2 = _pose.shiftBaseStationToFrame(pt2);

	return_code = wrapLine(s, pt1, pt2, aPathWrap, aWrapResult, p_flag);

   if (p_flag == true && return_code > 0) {
		// Convert the tangent points from the frame of the wrap object to the
		// frame of the wrap object's body
		aWrapResult.r1 = _pose.shiftFrameStationToBase(aWrapResult.r1);
		aWrapResult.r2 = _pose.shiftFrameStationToBase(aWrapResult.r2);

		// Convert the surface points (between the tangent points) from the frame of
		// the wrap object to the frame of the wrap object's body
		for (int i = 0; i < aWrapResult.wrap_pts.getSize(); i++)
			aWrapResult.wrap_pts.get(i) = _pose.shiftFrameStationToBase(aWrapResult.wrap_pts.get(i));
   }

   return return_code;
}
예제 #4
0
DBOOL PathListData::Copy(HOBJECT hPathPoint)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!hPathPoint || !pServerDE) return DFALSE;

    // Get the Object Position
	pServerDE->GetObjectPos(hPathPoint, &m_vPos);
	char* pName = pServerDE->GetObjectName(hPathPoint);
	if (pName)
	{
		m_hstrName = pServerDE->CreateString(pName);
	}
    
    // Get the Objects action
    PathPoint *pPathPoint = (PathPoint*)pServerDE->HandleToObject(hPathPoint);

    HSTRING hstrAction = pPathPoint->GetActionTarget();
	if (hstrAction)
	{
		m_hstrActionTarget = pServerDE->CopyString(hstrAction);
	}

    hstrAction = pPathPoint->GetActionMessage();
	if (hstrAction)
	{
		m_hstrActionMessage = pServerDE->CopyString(hstrAction);
	}

	return DTRUE;
}
예제 #5
0
PathPoint* GeometryPath::
appendNewPathPoint(const std::string& proposedName, 
                   PhysicalFrame& aBody, const SimTK::Vec3& aPositionOnBody)
{
    PathPoint* newPoint = new PathPoint();
    newPoint->setBody(aBody);
    newPoint->setName(proposedName);
    newPoint->set_location(aPositionOnBody);
    upd_PathPointSet().adoptAndAppend(newPoint);

    return newPoint;
}
예제 #6
0
PathPoint PathPoint::withChangedPointType (const Path::Iterator::PathElementType newType,
                                           const Rectangle<int>& parentArea) const
{
    PathPoint p (*this);

    if (newType != p.type)
    {
        int oldNumPoints = getNumPoints();
        p.type = newType;
        int numPoints = p.getNumPoints();

        if (numPoints != oldNumPoints)
        {
            double lastX, lastY;
            double x, y, w, h;

            p.pos [numPoints - 1] = p.pos [oldNumPoints - 1];
            p.pos [numPoints - 1].getRectangleDouble (x, y, w, h, parentArea, owner->getDocument()->getComponentLayout());

            const int index = owner->points.indexOf (this);

            if (PathPoint* lastPoint = owner->points [index - 1])
            {
                lastPoint->pos [lastPoint->getNumPoints() - 1]
                            .getRectangleDouble (lastX, lastY, w, h, parentArea, owner->getDocument()->getComponentLayout());
            }
            else
            {
                jassertfalse;
                lastX = x;
                lastY = y;
            }

            for (int i = 0; i < numPoints - 1; ++i)
            {
                p.pos[i] = p.pos [numPoints - 1];

                p.pos[i].updateFrom (lastX + (x - lastX) * (i + 1) / numPoints,
                                     lastY + (y - lastY) * (i + 1) / numPoints,
                                     w, h,
                                     parentArea,
                                     owner->getDocument()->getComponentLayout());
            }
        }
    }

    return p;
}
예제 #7
0
PathPoint* PathPoint::makePathPointOfType(PathPoint* aPoint, const string& aNewTypeName)
{
    PathPoint* newPoint = NULL;
    cout << "PathPoint::makePathPointOfType()" << endl;
    if (aPoint != NULL) {
        Object* newObject = Object::newInstanceOfType(aNewTypeName);
        if (newObject) {
            newPoint = dynamic_cast<PathPoint*>(newObject);
            if (newPoint) {
                // Copy the contents from aPoint.
                newPoint->init(*aPoint);
            }
        }
    }

    return newPoint;
}
예제 #8
0
void BezierController::MakeSegment(float time, 
                                   float inc,
                                   const PathPoint& p1,
                                   const PathPoint& p2,
                                   const PathPoint& p3,
                                   const PathPoint& p4)
{
   osg::Vec3 pos, tangent;

   for (int i = 0; i < 3; ++i)
   {
      pos[i] = (BlendFunction(inc,0) * p1.GetPosition()[i]) +
               (BlendFunction(inc,1) * p2.GetPosition()[i]) +
               (BlendFunction(inc,2) * p3.GetPosition()[i]) +
               (BlendFunction(inc,3) * p4.GetPosition()[i]);

      //tangent[i] = (TangentFunction(inc,1) * p2.GetPosition()[i]) + (TangentFunction(inc,2) * p3.GetPosition()[i]) + (TangentFunction(inc,3) * p4.GetPosition()[i]);
   }

   osg::Quat quat;
   quat.slerp(1.0 - inc, p4.GetOrientation(), p1.GetOrientation());

   PathData pd;
   pd.mTime = time;
   pd.mPoint.SetPosition(pos);
   pd.mPoint.SetOrientation(quat);

   mPath.push_back(pd);
}
예제 #9
0
// get the path as PointForceDirections directions 
// CAUTION: the return points are heap allocated; you must delete them yourself! 
// (TODO: that is really lame)
void GeometryPath::
getPointForceDirections(const SimTK::State& s, 
                        OpenSim::Array<PointForceDirection*> *rPFDs) const
{
    int i;
    PathPoint* start;
    PathPoint* end;
    const OpenSim::PhysicalFrame* startBody;
    const OpenSim::PhysicalFrame* endBody;
    const Array<PathPoint*>& currentPath = getCurrentPath(s);

    int np = currentPath.getSize();
    rPFDs->ensureCapacity(np);
    
    for (i = 0; i < np; i++) {
        PointForceDirection *pfd = 
            new PointForceDirection(currentPath[i]->getLocation(), 
                                    currentPath[i]->getBody(), Vec3(0));
        rPFDs->append(pfd);
    }

    for (i = 0; i < np-1; i++) {
        start = currentPath[i];
        end = currentPath[i+1];
        startBody = &start->getBody();
        endBody = &end->getBody();

        if (startBody != endBody)
        {
            Vec3 posStart, posEnd;
            Vec3 direction(0);

            // Find the positions of start and end in the inertial frame.
            //engine.getPosition(s, start->getBody(), start->getLocation(), posStart);
            posStart = start->getLocationInGround(s);
            
            //engine.getPosition(s, end->getBody(), end->getLocation(), posEnd);
            posEnd = end->getLocationInGround(s);

            // Form a vector from start to end, in the inertial frame.
            direction = (posEnd - posStart);

            // Check that the two points are not coincident.
            // This can happen due to infeasible wrapping of the path,
            // when the origin or insertion enters the wrapping surface.
            // This is a temporary fix, since the wrap algorithm should
            // return NaN for the points and/or throw an Exception- aseth
            if (direction.norm() < SimTK::SignificantReal){
                direction = direction*SimTK::NaN;
            }
            else{
                direction = direction.normalize();
            }

            // Get resultant direction at each point 
            rPFDs->get(i)->addToDirection(direction);
            rPFDs->get(i+1)->addToDirection(-direction);
        }
    }
}
예제 #10
0
void PaintElementPath::setCurrentBounds (const Rectangle<int>& b,
                                         const Rectangle<int>& parentArea,
                                         const bool /*undoable*/)
{
    Rectangle<int> newBounds (b);
    newBounds.setSize (jmax (1, newBounds.getWidth()),
                       jmax (1, newBounds.getHeight()));

    const Rectangle<int> current (getCurrentBounds (parentArea));

    if (newBounds != current)
    {
        const int borderSize = getBorderSize();

        const int dx = newBounds.getX() - current.getX();
        const int dy = newBounds.getY() - current.getY();

        const double scaleStartX = current.getX() + borderSize;
        const double scaleStartY = current.getY() + borderSize;
        const double scaleX = (newBounds.getWidth() - borderSize * 2) / (double) (current.getWidth() - borderSize * 2);
        const double scaleY = (newBounds.getHeight() - borderSize * 2) / (double) (current.getHeight() - borderSize * 2);

        for (int i = 0; i < points.size(); ++i)
        {
            PathPoint* const destPoint = points.getUnchecked(i);
            PathPoint p (*destPoint);

            for (int j = p.getNumPoints(); --j >= 0;)
                rescalePoint (p.pos[j], dx, dy,
                              scaleX, scaleY,
                              scaleStartX, scaleStartY,
                              parentArea);

            perform (new ChangePointAction (destPoint, i, p), "Move path");
        }
    }
}
예제 #11
0
PathPoint Path::update(Vector3<float> refPos, Vector3<float> playerPos)
{
  float D_val;
  PathPoint current = getCurrent();
  PathPoint previous = getPrevious();
  float diffX = refPos.x - current.getPosition().x;
  float diffY = refPos.y - current.getPosition().y;
  float diffZ = refPos.z - current.getPosition().z;
  float playerDistFromPlane = 0;
  float firstDistFromPlane = 0;
  Vector3<float> vect1 (current.getPosition().x - previous.getPosition().x,
			current.getPosition().y - previous.getPosition().y,
			current.getPosition().z - previous.getPosition().z);

  Vector3<float> vect2 (current.getPosition().x + current.getUp().x,
			current.getPosition().y + current.getUp().y,
			current.getPosition().z + current.getUp().z);

  Vector3<float> normal;
  float distance = sqrt(diffX * diffX + diffY * diffY + diffZ * diffZ);
  PathPoint firstChoice = getAt(current.getFirstID());

  if (distance < RANGE_CHECK) {
    if (current.getNumberOfIDs() == 1) {

      setChoice(current.getFirstID());
      return getCurrent();
    }

    normal = vect1.Cross(vect2).Normalized();
    D_val = (current.getPosition().x * normal.x + current.getPosition().y 
	     * normal.y + current.getPosition().z * normal.z) * -1.0f;
    
    playerDistFromPlane = (normal.x * playerPos.x) + 
       (normal.y * playerPos.y) + (normal.z * playerPos.z) + D_val;
    
    if (abs(playerDistFromPlane) < MID_BUFFER_WIDTH && 
	current.getNumberOfIDs() == 3) {
      setChoice(current.getThirdID());
      return getCurrent();
    }
    
    firstDistFromPlane = normal.x * firstChoice.getPosition().x 
       + normal.y * firstChoice.getPosition().y 
       + normal.z * firstChoice.getPosition().z + D_val;

    if (playerDistFromPlane / abs(playerDistFromPlane) == 
	firstDistFromPlane / abs(firstDistFromPlane)) {
      setChoice(current.getFirstID());
      return getCurrent();
    }
    else {
      setChoice(current.getSecondID());
      return getCurrent();
    }
  }
  return getCurrent();
}
예제 #12
0
bool OpenSimContext::isActivePathPoint(PathPoint& mp) {
  return mp.isActive(*_configState);
};
예제 #13
0
void OpenSimContext::setBody(PathPoint& pathPoint, Body&  newBody) {
   pathPoint.changeBodyPreserveLocation(*_configState, newBody);
   this->recreateSystemAfterSystemExists();
   realizeVelocity();
}
예제 #14
0
/* add in the equivalent spatial forces on bodies for an applied tension 
    along the GeometryPath to a set of bodyForces */
void GeometryPath::addInEquivalentForces(const SimTK::State& s,
    const double& tension, 
    SimTK::Vector_<SimTK::SpatialVec>& bodyForces,
    SimTK::Vector& mobilityForces) const
{
    PathPoint* start = NULL;
    PathPoint* end = NULL;
    const SimTK::MobilizedBody* bo = NULL;
    const SimTK::MobilizedBody* bf = NULL;
    const Array<PathPoint*>& currentPath = getCurrentPath(s);
    int np = currentPath.getSize();

    const SimTK::SimbodyMatterSubsystem& matter = 
                                        getModel().getMatterSubsystem();

    // start point, end point,  direction, and force vectors in ground
    Vec3 po(0), pf(0), dir(0), force(0);
    // partial velocity of point in body expressed in ground 
    Vec3 dPodq_G(0), dPfdq_G(0);

    // gen force (torque) due to moving point under tension
    double fo, ff;

    for (int i = 0; i < np-1; ++i) {
        start = currentPath[i];
        end = currentPath[i+1];

        bo = &start->getBody().getMobilizedBody();
        bf = &end->getBody().getMobilizedBody();

        if (bo != bf) {
            // Find the positions of start and end in the inertial frame.
            po = start->getLocationInGround(s);
            pf = end->getLocationInGround(s);

            // Form a vector from start to end, in the inertial frame.
            dir = (pf - po);

            // Check that the two points are not coincident.
            // This can happen due to infeasible wrapping of the path,
            // when the origin or insertion enters the wrapping surface.
            // This is a temporary fix, since the wrap algorithm should
            // return NaN for the points and/or throw an Exception- aseth
            if (dir.norm() < SimTK::SignificantReal){
                dir = dir*SimTK::NaN;
            }
            else{
                dir = dir.normalize();
            }

            force = tension*dir;

            const MovingPathPoint* mppo =
                dynamic_cast<MovingPathPoint *>(start);

            // do the same for the end point of this segment of the path
            const MovingPathPoint* mppf =
                dynamic_cast<MovingPathPoint *>(end);

            // add in the tension point forces to body forces
            if (mppo) {// moving path point location is a function of the state
                // transform of the frame of the point to the base mobilized body
                auto X_BF = mppo->getParentFrame().findTransformInBaseFrame();
                bo->applyForceToBodyPoint(s, X_BF*mppo->getLocation(s), force,
                    bodyForces);
            }
            else {
                // transform of the frame of the point to the base mobilized body
                auto X_BF = start->getParentFrame().findTransformInBaseFrame();
                bo->applyForceToBodyPoint(s, X_BF*start->getLocation(), force,
                    bodyForces);
            }

            if (mppf) {// moving path point location is a function of the state
                // transform of the frame of the point to the base mobilized body
                auto X_BF = mppf->getParentFrame().findTransformInBaseFrame();
                bf->applyForceToBodyPoint(s, X_BF*mppf->getLocation(s), -force,
                    bodyForces);
            }
            else {
                // transform of the frame of the point to the base mobilized body
                auto X_BF = end->getParentFrame().findTransformInBaseFrame();
                bf->applyForceToBodyPoint(s, X_BF*end->getLocation(), -force,
                    bodyForces);
            }

            // Now account for the work being done by virtue of the moving
            // path point motion relative to the body it is on
            if(mppo){
                // torque (genforce) contribution due to relative movement 
                // of a via point w.r.t. the body it is connected to.
                dPodq_G = bo->expressVectorInGroundFrame(s, start->getdPointdQ(s));
                fo = ~dPodq_G*force;            

                // get the mobilized body the coordinate is couple to.
                const SimTK::MobilizedBody& mpbod =
                    matter.getMobilizedBody(mppo->getXCoordinate().getBodyIndex());

                // apply the generalized (mobility) force to the coordinate's body
                mpbod.applyOneMobilityForce(s, 
                    mppo->getXCoordinate().getMobilizerQIndex(), 
                    fo, mobilityForces);
            }

            if(mppf){
                dPfdq_G = bf->expressVectorInGroundFrame(s, end->getdPointdQ(s));
                ff = ~dPfdq_G*(-force);

                // get the mobilized body the coordinate is couple to.
                const SimTK::MobilizedBody& mpbod =
                    matter.getMobilizedBody(mppf->getXCoordinate().getBodyIndex());

                mpbod.applyOneMobilityForce(s, 
                    mppf->getXCoordinate().getMobilizerQIndex(), 
                    ff, mobilityForces);
            }
        }       
    }
}