//------------------------------------------------------------------------------ // GENERATE DECORATIONS //------------------------------------------------------------------------------ // The GeometryPath takes care of drawing itself here, using information it // can extract from the supplied state, including position information and // color information that may have been calculated as late as Stage::Dynamics. // For example, muscles may want the color to reflect activation level and // other path-using components might want to use forces (tension). We will // ensure that the state has been realized to Stage::Dynamics before looking // at it. (It is only guaranteed to be at Stage::Position here.) void GeometryPath:: generateDecorations(bool fixed, const ModelDisplayHints& hints, const SimTK::State& state, SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const { // There is no fixed geometry to generate here. if (fixed) { return; } // Ensure that the state has been realized to Stage::Dynamics to give // clients of this path a chance to calculate meaningful color information. this->getModel().getMultibodySystem().realize(state, SimTK::Stage::Dynamics); this->updateDisplayPath(state); // Even though these are Points which are Components they are completey // orphaned and not part of any system since they are populated during // a simulation. TODO we need another data structure to be a DecorativePath // which simply an array of points in ground or on MBs. // Trying to getLocationInGround(state) will faile due to no underlying system. const Array<PathPoint*>& points = getCurrentDisplayPath(state); if (points.getSize() == 0) { return; } const PathPoint* lastPoint = points[0]; MobilizedBodyIndex mbix(0); Vec3 lastPos = lastPoint->getLocationInGround(state); if (hints.get_show_path_points()) DefaultGeometry::drawPathPoint(mbix, lastPos, getColor(state), appendToThis); Vec3 pos; for (int j = 1; j < points.getSize(); j++) { const PathPoint* point = points[j]; // the body (PhysicalFrame) IS part of the actual Model and its system // so we can ask it for its transform w.r.t. Ground pos = point->getBody().getTransformInGround(state)*point->getLocation(); if (hints.get_show_path_points()) DefaultGeometry::drawPathPoint(mbix, pos, getColor(state), appendToThis); // Line segments will be in ground frame appendToThis.push_back(DecorativeLine(lastPos, pos) .setLineThickness(4) .setColor(getColor(state)).setBodyId(0).setIndexOnBody(j)); lastPos = pos; } }
// Implement generateDecorations by WrapCylinder to replace the previous out of place implementation // in ModelVisualizer void WrapCylinder::generateDecorations(bool fixed, const ModelDisplayHints& hints, const SimTK::State& state, SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const { Super::generateDecorations(fixed, hints, state, appendToThis); if (fixed) return; if (hints.get_show_wrap_geometry()) { const Appearance& defaultAppearance = get_Appearance(); if (!defaultAppearance.get_visible()) return; const Vec3 color = defaultAppearance.get_color(); SimTK::Transform ztoy; // Make transform that takes z axis to y axis due to different // assumptions between DecorativeCylinder aligned with y and // WrapCylinder aligned with z ztoy.updR().setRotationFromAngleAboutX(SimTK_PI / 2); const SimTK::Transform& X_GB = getFrame().getTransformInGround(state); SimTK::Transform X_GW = X_GB*getTransform()*ztoy; appendToThis.push_back( SimTK::DecorativeCylinder(get_radius(), get_length() / 2) .setTransform(X_GW).setResolution(2.0) .setColor(color).setOpacity(defaultAppearance.get_opacity()) .setScale(1).setRepresentation(defaultAppearance.get_representation())); } }
void Marker::generateDecorations(bool fixed, const ModelDisplayHints& hints, const SimTK::State& state, SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const { Super::generateDecorations(fixed, hints, state, appendToThis); if (!fixed) return; if (!hints.get_show_markers()) return; // @TODO default color, size, shape should be obtained from hints const Vec3 color = hints.get_marker_color(); const OpenSim::PhysicalFrame& frame = getParentFrame(); //const Frame& bf = frame.findBaseFrame(); //SimTK::Transform bTrans = frame.findTransformInBaseFrame(); //const Vec3& p_BM = bTrans*get_location(); appendToThis.push_back( SimTK::DecorativeSphere(.01).setBodyId(frame.getMobilizedBodyIndex()) .setColor(color).setOpacity(1.0) .setTransform(get_location())); }
// Implement generateDecorations by WrapEllipsoid to replace the previous out of place implementation // in ModelVisualizer void WrapEllipsoid::generateDecorations(bool fixed, const ModelDisplayHints& hints, const SimTK::State& state, SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const { Super::generateDecorations(fixed, hints, state, appendToThis); if (fixed) return; if (hints.get_show_wrap_geometry()) { const Vec3 color(SimTK::Cyan); const SimTK::Transform& X_GB = getFrame().getTransformInGround(state); SimTK::Transform X_GW = X_GB*getTransform(); appendToThis.push_back( SimTK::DecorativeEllipsoid(getRadii()) .setTransform(X_GW).setResolution(2.0) .setColor(color).setOpacity(0.5)); } }
// Implement generateDecorations by WrapTorus to replace the previous out of place implementation // in ModelVisualizer, not implemented yet in API visualizer void WrapTorus::generateDecorations(bool fixed, const ModelDisplayHints& hints, const SimTK::State& state, SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const { Super::generateDecorations(fixed, hints, state, appendToThis); if (fixed) return; if (hints.get_show_wrap_geometry()) { const Appearance& defaultAppearance = get_Appearance(); if (!defaultAppearance.get_visible()) return; const Vec3 color = defaultAppearance.get_color(); const SimTK::Transform& X_GB = getFrame().getTransformInGround(state); SimTK::Transform X_GW = X_GB*getTransform(); appendToThis.push_back( SimTK::DecorativeTorus(getOuterRadius(), getInnerRadius()) .setTransform(X_GW).setResolution(2.0) .setColor(color).setOpacity(defaultAppearance.get_opacity()) .setScale(1).setRepresentation(defaultAppearance.get_representation())); } }