1 #ifndef OPENSIM_GEOMETRY_H_ 2 #define OPENSIM_GEOMETRY_H_ 3 /* -------------------------------------------------------------------------- * 4 * OpenSim: Geometry.h * 5 * -------------------------------------------------------------------------- * 6 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation. * 7 * See http://opensim.stanford.edu and the NOTICE file for more information. * 8 * OpenSim is developed at Stanford University and supported by the US * 9 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA * 10 * through the Warrior Web program. * 11 * * 12 * Copyright (c) 2005-2017 Stanford University and the Authors * 13 * Author(s): Ayman Habib * 14 * * 15 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 16 * not use this file except in compliance with the License. You may obtain a * 17 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 18 * * 19 * Unless required by applicable law or agreed to in writing, software * 20 * distributed under the License is distributed on an "AS IS" BASIS, * 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 22 * See the License for the specific language governing permissions and * 23 * limitations under the License. * 24 * -------------------------------------------------------------------------- */ 25 26 #include <OpenSim/Common/Component.h> 27 #include "Appearance.h" 28 29 namespace OpenSim { 30 31 class Frame; 32 //============================================================================= 33 //============================================================================= 34 /** 35 Class Geometry is intended to be used as the base class for all 36 geometry that needs to be represented in the system, including mesh files, 37 and built in analytic shapes. Any ModelComponent can specify a list of 38 Geometry items to represent itself in graphics window. The relation between 39 a ModelComponent and specific Geometry utilizes the Component mechanism, as 40 the specific pieces of geometry are treated as subcomponents. The placement 41 of the Geometry in 3D space is computed from the Frame that the Geometry is 42 "Connected" to. 43 44 Geometry (and all its subclasses) serve as the set of higher level primitives 45 available to OpenSim component writers to express the Geometry of interest. 46 The Geometry class handles serialization and also the translation to a set of 47 DecorativeGeometry objects that gets passed to the Visualization system to be 48 rendered. 49 50 @author Ayman Habib 51 */ 52 53 // Base Geometry 54 class OSIMSIMULATION_API Geometry : public Component { 55 OpenSim_DECLARE_ABSTRACT_OBJECT(Geometry, Component); 56 public: 57 //============================================================================== 58 // PROPERTIES 59 //============================================================================== 60 OpenSim_DECLARE_PROPERTY(scale_factors, SimTK::Vec3, 61 "Scale factors in X, Y, Z directions respectively."); 62 OpenSim_DECLARE_UNNAMED_PROPERTY(Appearance, 63 "Default appearance attributes for this Geometry"); 64 65 //============================================================================= 66 // SOCKETS 67 //============================================================================= 68 OpenSim_DECLARE_SOCKET_FD(frame, Frame, 69 "The frame to which this geometry is attached. Note, being connected " 70 "to a Frame means its transform is used to position this Geometry." ); 71 //============================================================================= 72 // INPUTS 73 //============================================================================= 74 OpenSim_DECLARE_INPUT(transform, SimTK::Transform, SimTK::Stage::Position, 75 "The transform that positions the Geometry in Ground so it can be " 76 "positioned. Note, either the Geometry is attached to a Frame OR " 77 "the input transform can be supplied, but not both. "); 78 79 //-------------------------------------------------------------------------- 80 // CONSTRUCTION 81 //-------------------------------------------------------------------------- 82 public: 83 /// Default constructor 84 Geometry(); 85 86 /// Convenience constructor that takes a Frame Geometry(const Frame & frame)87 Geometry(const Frame& frame) : Geometry() { 88 setFrame(frame); 89 } 90 91 /// Default destructor ~Geometry()92 virtual ~Geometry() {} 93 /** Interface methods to handle the Frame which the Geometry is attached to. */ 94 /** %Set the Frame of attachment **/ 95 void setFrame(const Frame& frame); 96 /** Return a reference to the name of the Frame to which 97 this Geometry is attached (using a Socket). **/ 98 99 /** Return a reference to the actual Frame to which this Geometry 100 is attached. */ 101 const Frame& getFrame() const; 102 //========================================================================== 103 // METHODS 104 //========================================================================== 105 // DEPRECATED: following methods are used by the GUI in version 3.3 and 106 // will be removed before release 4.0 in favor of a mechanism that 107 // handles local/global/shared Appearance objects 108 /// Convenient access to set Appearance/Color 109 /// color is RGB, each components is in the range [0, 1]. setColor(const SimTK::Vec3 & color)110 void setColor(const SimTK::Vec3& color) { 111 upd_Appearance().set_color(color); 112 }; 113 114 /// Convenient access to get Appearance/Color 115 /// returns RGB , each components is in the range [0, 1]. getColor()116 const SimTK::Vec3& getColor() const { 117 return get_Appearance().get_color(); 118 }; 119 120 /// Convenient access to set Appearance/Opacity setOpacity(const double opacity)121 void setOpacity(const double opacity) { 122 upd_Appearance().set_opacity(opacity); 123 }; 124 /// Convenient access to get Appearance/Opacity getOpacity()125 const double getOpacity() { 126 return get_Appearance().get_opacity(); 127 }; 128 129 /// Convenient access to set Appearance/representation setRepresentation(OpenSim::VisualRepresentation rep)130 void setRepresentation(OpenSim::VisualRepresentation rep) { 131 upd_Appearance().set_representation(rep); 132 }; 133 /// Convenient access to get Appearance/representation getRepresentation()134 OpenSim::VisualRepresentation getRepresentation() { return 135 get_Appearance().get_representation(); 136 }; 137 // END DEPRECATED 138 139 /// Implement method from Component interface. Subclasses only need to 140 /// implement implementCreateDecorativeGeometry to generate an Array of 141 /// SimTK::DecorativeGeometry. From then on, setting Transforms & Appearance 142 /// is handled by the base class Geometry to avoid duplication. 143 void generateDecorations 144 (bool fixed, 145 const ModelDisplayHints& hints, 146 const SimTK::State& state, 147 SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const override; 148 149 150 protected: 151 /// Map this Geometry into a list of primitives aka SimTK::DecorativeGeometry 152 /// and return the result in the passed in Array. 153 virtual void implementCreateDecorativeGeometry( 154 SimTK::Array_<SimTK::DecorativeGeometry>&) const = 0; 155 156 void extendFinalizeConnections(Component& root) override; 157 158 private: 159 // Compute Transform of this geometry relative to its base frame, utilizing 160 // passed in state. Both transform and body_id are set in the passed-in 161 // decorations as a side effect. 162 void setDecorativeGeometryTransform( 163 SimTK::Array_<SimTK::DecorativeGeometry>& decorations, 164 const SimTK::State& state) const; 165 166 // Manage Appearance (how the Geometry is rendered) by applying Appearance 167 // from Geometry to DecorativeGeometry. setDecorativeGeometryAppearance(SimTK::DecorativeGeometry & decoration)168 void setDecorativeGeometryAppearance( 169 SimTK::DecorativeGeometry& decoration) const { 170 decoration.setColor(get_Appearance().get_color()); 171 decoration.setOpacity(get_Appearance().get_opacity()); 172 if (get_Appearance().get_visible()) 173 decoration.setRepresentation( 174 (VisualRepresentation) 175 get_Appearance().get_representation()); 176 else 177 decoration.setRepresentation(SimTK::DecorativeGeometry::Hide); 178 }; 179 180 /// Specify the default values for properties of Geometry constructProperties()181 void constructProperties() { 182 constructProperty_scale_factors(SimTK::Vec3(1)); 183 constructProperty_Appearance(Appearance()); 184 } 185 setNull()186 void setNull() { 187 setAuthors("Ayman Habib"); 188 } 189 //============================================================================= 190 }; // END of class Geometry 191 192 /** 193 * LineGeometry is a utility class used to abstract a line segment. 194 * It is used by muscle segments so that it's as small and useful as possible. 195 * 196 * NOTE: LineGeometry assumes its Frame is Ground! 197 * TODO make LineGeometry draw between actual Points! 198 */ 199 class OSIMSIMULATION_API LineGeometry : public Geometry 200 { 201 OpenSim_DECLARE_CONCRETE_OBJECT(LineGeometry, Geometry); 202 public: 203 // Property start_point 204 OpenSim_DECLARE_PROPERTY(start_point, SimTK::Vec3, 205 "Line start point."); 206 // Property end_point 207 OpenSim_DECLARE_PROPERTY(end_point, SimTK::Vec3, 208 "Line end point."); 209 /// Convenience constructor that takes two end points LineGeometry(SimTK::Vec3 & aPoint1,SimTK::Vec3 & aPoint2)210 LineGeometry(SimTK::Vec3& aPoint1, SimTK::Vec3& aPoint2): 211 Geometry() { 212 constructProperties(); 213 setPoints(aPoint1, aPoint2); 214 } 215 216 /// default constructor, creates line (0,0,0)-(1,1,1) LineGeometry()217 LineGeometry(): 218 Geometry() { 219 constructProperties(); 220 } 221 222 /// destructor ~LineGeometry()223 virtual ~LineGeometry() {} 224 /// Get end points as Vec3 in passed in arguments getPoints(SimTK::Vec3 & rPoint1,SimTK::Vec3 & rPoint2)225 void getPoints(SimTK::Vec3& rPoint1, SimTK::Vec3& rPoint2) const { 226 rPoint1 = get_start_point(); 227 rPoint2 = get_end_point(); 228 } 229 /// %Set end points from passed in arguments setPoints(SimTK::Vec3 & aPoint1,SimTK::Vec3 & aPoint2)230 void setPoints(SimTK::Vec3& aPoint1, SimTK::Vec3& aPoint2) { 231 upd_start_point() = aPoint1; 232 upd_end_point() = aPoint2; 233 } 234 235 protected: 236 /** Virtual method to map LineGeometry to SimTK::Array of 237 SimTK::DecorativeGeometry. Appearance, Transforms are handled by base 238 Geometry class. */ 239 void implementCreateDecorativeGeometry( 240 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 241 private: constructProperties()242 void constructProperties() { 243 constructProperty_start_point(SimTK::Vec3(0)); 244 constructProperty_end_point(SimTK::Vec3(1)); 245 } 246 }; 247 /** 248 * Arrow is a Geometry subclass used to represent an arrow. The arrow goes from 249 * start_point (Property) and has direction (Property) and length (Property) 250 * 251 */ 252 class OSIMSIMULATION_API Arrow : public Geometry 253 { 254 OpenSim_DECLARE_CONCRETE_OBJECT(Arrow, Geometry); 255 public: 256 // Property start_point 257 OpenSim_DECLARE_PROPERTY(start_point, SimTK::Vec3, 258 "Arrow start point."); 259 // Property direction 260 OpenSim_DECLARE_PROPERTY(direction, SimTK::Vec3, 261 "direction of Arrow"); 262 263 OpenSim_DECLARE_PROPERTY(length, double, "length of Arrow"); 264 /// constructor that takes startPoint, direction vector and length Arrow(SimTK::Vec3 & aPoint1,SimTK::UnitVec3 & aUnitDir,double aLength)265 Arrow(SimTK::Vec3& aPoint1, SimTK::UnitVec3& aUnitDir, double aLength) 266 { 267 constructProperties(); 268 updProperty_start_point() = aPoint1; 269 updProperty_direction() = aUnitDir; 270 updProperty_length() = aLength; 271 } 272 /// Default constructor that creates Arrow of length 1 starting at origin 273 /// in the direction (1,1,1) Arrow()274 Arrow() 275 { 276 constructProperties(); 277 } 278 /// destructor ~Arrow()279 virtual ~Arrow() {} 280 281 protected: 282 /** Virtual method to map Arrow to SimTK::Array of SimTK::DecorativeGeometry. 283 Appearance, Transforms are handled by base Geometry class. */ 284 void implementCreateDecorativeGeometry( 285 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 286 private: constructProperties()287 void constructProperties() { 288 constructProperty_start_point(SimTK::Vec3(0)); 289 constructProperty_direction(SimTK::Vec3(1)); 290 constructProperty_length(1.0); 291 } 292 }; 293 294 295 /** 296 * Abstract class for analytical geometry (e.g. surfaces of revolution) whose 297 * rendering is optimized by the graphics library (e.g. threejs). Unlike other 298 * geometry, property edits require a recreation of the AnalyticGeometry on 299 * the renderer and not simple updates. AnalyticGeometry is the base class for 300 * Sphere, Cylinder, Cone, Ellipsoid and Torus geometry. 301 */ 302 class OSIMSIMULATION_API AnalyticGeometry : public Geometry 303 { 304 OpenSim_DECLARE_ABSTRACT_OBJECT(AnalyticGeometry, Geometry); 305 306 public: AnalyticGeometry()307 AnalyticGeometry() {} ~AnalyticGeometry()308 virtual ~AnalyticGeometry() {} 309 }; 310 /** 311 * A class to represent Sphere geometry. 312 */ 313 class OSIMSIMULATION_API Sphere : public AnalyticGeometry 314 { 315 OpenSim_DECLARE_CONCRETE_OBJECT(Sphere, AnalyticGeometry); 316 public: 317 OpenSim_DECLARE_PROPERTY(radius, double, 318 "Radius of sphere, defaults to 1.0"); 319 /// Default constructor, creates a sphere of radius 1.0 Sphere()320 Sphere() : 321 AnalyticGeometry() 322 { 323 constructProperties(); 324 } 325 /// Another constructor that takes in a specified radius Sphere(double radius)326 Sphere(double radius): 327 AnalyticGeometry() 328 { 329 constructProperties(); 330 upd_radius() = radius; 331 } 332 /// destructor ~Sphere()333 ~Sphere() {} 334 335 protected: 336 /// Virtual method to map Sphere to Array of SimTK::DecorativeGeometry. 337 /// Appearance, Transforms are handled by base Geometry class 338 void implementCreateDecorativeGeometry( 339 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 340 private: constructProperties()341 void constructProperties() { 342 constructProperty_radius(1.0); 343 } 344 }; // Sphere 345 346 /** 347 * A class to represent an Ellipsoid geometry. 348 */ 349 class OSIMSIMULATION_API Ellipsoid : public AnalyticGeometry 350 { 351 OpenSim_DECLARE_CONCRETE_OBJECT(Ellipsoid, AnalyticGeometry); 352 public: 353 OpenSim_DECLARE_PROPERTY(radii, SimTK::Vec3, "Radii of Ellipsoid."); 354 /// Default constructor, creates an Ellipsoid of radii 0.5, 1., 2. Ellipsoid()355 Ellipsoid() : 356 AnalyticGeometry() 357 { 358 constructProperties(); 359 } 360 /// Constructor that takes in three radii Ellipsoid(double radius1,double radius2,double radius3)361 Ellipsoid(double radius1, double radius2, double radius3): 362 AnalyticGeometry(){ 363 constructProperties(); 364 setEllipsoidParams(radius1, radius2, radius3); 365 } 366 /// destructor ~Ellipsoid()367 ~Ellipsoid() {} 368 /// Convenience interface to set radii setEllipsoidParams(double radius1,double radius2,double radius3)369 void setEllipsoidParams(double radius1, double radius2, double radius3) 370 { 371 upd_radii()[0] = radius1; 372 upd_radii()[1] = radius2; 373 upd_radii()[2] = radius3; 374 } 375 protected: 376 /** Virtual method to map Ellipsoid to SimTK::Array_ of 377 SimTK::DecorativeGeometry. Appearance, Transforms are handled by base 378 Geometry class. */ 379 void implementCreateDecorativeGeometry( 380 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 381 private: constructProperties()382 void constructProperties() { 383 constructProperty_radii(SimTK::Vec3(0.5, 1., 2.)); 384 } 385 }; 386 387 388 /** 389 * A class to represent a Cylinder geometry. 390 */ 391 392 class OSIMSIMULATION_API Cylinder : public AnalyticGeometry 393 { 394 OpenSim_DECLARE_CONCRETE_OBJECT(Cylinder, AnalyticGeometry); 395 public: 396 // Property radius 397 OpenSim_DECLARE_PROPERTY(radius, double, "Radius of cylinder."); 398 // Property half_height 399 OpenSim_DECLARE_PROPERTY(half_height, double, "Half-Height of cylinder."); 400 /// Default constructor Cylinder()401 Cylinder() : 402 AnalyticGeometry() 403 { 404 constructProperties(); 405 } 406 /// Convenience constructor that takes radius and half-height Cylinder(const double radius,const double hheight)407 Cylinder(const double radius, const double hheight): 408 AnalyticGeometry() 409 { 410 constructProperties(); 411 upd_radius() = radius; 412 upd_half_height() = hheight; 413 } 414 /// destructor ~Cylinder()415 ~Cylinder() {} 416 /// Convenient way to get the two parameters that define the cylinder getCylinderParams(SimTK::Vec2 & params)417 void getCylinderParams(SimTK::Vec2& params) const 418 { 419 params[0] = get_radius(); 420 params[1] = get_half_height(); 421 } 422 protected: 423 /** Virtual method to map Cylinder to SimTK::Array_ of SimTK::DecorativeGeometry. 424 Appearance, Transforms are handled by base Geometry class. */ 425 void implementCreateDecorativeGeometry( 426 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 427 private: constructProperties()428 void constructProperties() { 429 constructProperty_radius(0.5); 430 constructProperty_half_height(0.5); 431 } 432 }; 433 434 435 436 /** 437 * A class to represent a Cone geometry. 438 */ 439 440 class OSIMSIMULATION_API Cone : public AnalyticGeometry 441 { 442 OpenSim_DECLARE_CONCRETE_OBJECT(Cone, AnalyticGeometry); 443 public: 444 OpenSim_DECLARE_PROPERTY(origin, SimTK::Vec3, "origin of cone base"); 445 OpenSim_DECLARE_PROPERTY(direction, SimTK::Vec3, "direction of cone axis."); 446 OpenSim_DECLARE_PROPERTY(base_radius, double, "Base radius of cone."); 447 OpenSim_DECLARE_PROPERTY(height, double, "Height of cone."); 448 /// Default constructor Cone()449 Cone() : 450 AnalyticGeometry() 451 { 452 constructProperties(); 453 } 454 /// Convenience constructor that takes radius and half-height Cone(const SimTK::Vec3 & o,const SimTK::UnitVec3 & dir,double height,double base)455 Cone(const SimTK::Vec3& o, const SimTK::UnitVec3& dir, 456 double height, double base) : 457 AnalyticGeometry() 458 { 459 constructProperties(); 460 upd_origin() = o; 461 upd_direction() = SimTK::Vec3(dir); 462 upd_base_radius() = base; 463 upd_height() = height; 464 } 465 /// destructor ~Cone()466 ~Cone() {} 467 protected: 468 /** Method to map Cone to SimTK::Array of SimTK::DecorativeGeometry. 469 Appearance, Transforms are handled by base Geometry class. */ 470 void implementCreateDecorativeGeometry( 471 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 472 private: constructProperties()473 void constructProperties() { 474 constructProperty_origin(SimTK::Vec3(0)); 475 constructProperty_direction(SimTK::UnitVec3(1)); 476 constructProperty_base_radius(0.5); 477 constructProperty_height(1.0); 478 } 479 }; 480 481 /** 482 * A class to represent Torus geometry. The torus is centered at the 483 origin with the axial direction aligned to the z-axis. It is defined by 484 a ring_radius (radius of the circular centerline of the torus, measured 485 from the origin), and a cross_section (radius of the torus cross-section: 486 perpendicular distance from the circular centerline to the surface). 487 */ 488 class OSIMSIMULATION_API Torus : public AnalyticGeometry 489 { 490 OpenSim_DECLARE_CONCRETE_OBJECT(Torus, AnalyticGeometry); 491 public: 492 OpenSim_DECLARE_PROPERTY(cross_section, double, "Cross section radius"); 493 OpenSim_DECLARE_PROPERTY(ring_radius, double, "Radius of the torus ring."); 494 public: 495 /// Default constructor Torus()496 Torus(): 497 AnalyticGeometry() 498 {} 499 /// Constructor that takes in two radii Torus(const double ringRadius,const double crossSectionRadius)500 Torus(const double ringRadius, const double crossSectionRadius): 501 AnalyticGeometry() 502 { 503 upd_ring_radius()=ringRadius; 504 upd_cross_section()=crossSectionRadius; 505 } ~Torus()506 virtual ~Torus() {} 507 508 protected: 509 /** Method to map Cone to Array of SimTK::DecorativeGeometry. 510 Appearance, Transforms are handled by base Geometry class. */ implementCreateDecorativeGeometry(SimTK::Array_<SimTK::DecorativeGeometry> & decoGeoms)511 void implementCreateDecorativeGeometry( 512 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override {}; 513 }; 514 515 /** 516 * A class to represent Brick geometry. Brick is specified by three half_lengths 517 */ 518 class OSIMSIMULATION_API Brick : public Geometry 519 { 520 OpenSim_DECLARE_CONCRETE_OBJECT(Brick, Geometry); 521 public: 522 OpenSim_DECLARE_PROPERTY(half_lengths, SimTK::Vec3, 523 "Half lengths in X, Y, Z respectively."); 524 525 public: 526 /// Default constructor, makes a Brick with half-length 0.1,0.2,0.3 Brick()527 Brick() : 528 Geometry() 529 { 530 constructProperty_half_lengths(SimTK::Vec3(0.1, 0.2, 0.3)); 531 } 532 /// Convenience constructor with specified half-lengths Brick(const SimTK::Vec3 & halfLengths)533 Brick(const SimTK::Vec3& halfLengths) : 534 Geometry() 535 { 536 constructProperty_half_lengths(SimTK::Vec3(0.1, 0.2, 0.3)); 537 upd_half_lengths() = halfLengths; 538 } 539 /// Destructor ~Brick()540 ~Brick() {} 541 protected: 542 /// Method to map Brick to Array of SimTK::DecorativeGeometry. 543 void implementCreateDecorativeGeometry( 544 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 545 546 }; 547 /** 548 * A class to represent Mesh geometry that comes from a file. 549 * Supported file formats .vtp, .stl, .obj but will grow over time 550 */ 551 class OSIMSIMULATION_API Mesh : public Geometry 552 { 553 OpenSim_DECLARE_CONCRETE_OBJECT(Mesh, Geometry); 554 public: 555 OpenSim_DECLARE_PROPERTY(mesh_file, std::string, 556 "Name of geometry file."); 557 558 public: 559 /// Default constructor Mesh()560 Mesh() : 561 Geometry(), 562 cachedMesh(nullptr), 563 warningGiven(false) 564 { 565 constructProperty_mesh_file(""); 566 } 567 /// Constructor that takes a mesh file name Mesh(const std::string & geomFile)568 Mesh(const std::string& geomFile) : 569 Geometry(), 570 cachedMesh(nullptr), 571 warningGiven(false) 572 { 573 constructProperty_mesh_file(""); 574 upd_mesh_file() = geomFile; 575 } 576 /// destructor ~Mesh()577 virtual ~Mesh() {}; 578 /// Retrieve file name getGeometryFilename()579 const std::string& getGeometryFilename() const 580 { 581 return get_mesh_file(); 582 }; 583 protected: 584 // ModelComponent interface. 585 void extendFinalizeFromProperties() override; 586 587 protected: 588 /// Method to map Mesh to Array of SimTK::DecorativeGeometry. 589 void implementCreateDecorativeGeometry( 590 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 591 private: 592 // We cache the DecorativeMeshFile if we successfully 593 // load the mesh from file so we don't try loading from disk every frame. 594 // This is mutable since it is not part of the public interface. 595 mutable SimTK::ResetOnCopy<std::unique_ptr<SimTK::DecorativeMeshFile>> cachedMesh; 596 mutable bool warningGiven; 597 }; 598 599 /** 600 * A class to represent Frame geometry. Knobs that can be changed 601 * are in Appearance::Representation, size, thickness. 602 */ 603 class OSIMSIMULATION_API FrameGeometry : public Geometry 604 { 605 OpenSim_DECLARE_CONCRETE_OBJECT(FrameGeometry, Geometry); 606 public: 607 OpenSim_DECLARE_PROPERTY(display_radius, double, 608 "The radius of the arrow-shaft used to display the frame."); 609 /// Default constructor Geometry()610 FrameGeometry(double scale=0.2) : Geometry() 611 { 612 constructProperties(); 613 set_scale_factors(SimTK::Vec3(scale)); 614 } 615 /// destructor ~FrameGeometry()616 virtual ~FrameGeometry() {}; 617 618 void generateDecorations 619 (bool fixed, 620 const ModelDisplayHints& hints, 621 const SimTK::State& state, 622 SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const override; 623 protected: 624 /// Method to map FrameGeometry to Array of SimTK::DecorativeGeometry. 625 void implementCreateDecorativeGeometry( 626 SimTK::Array_<SimTK::DecorativeGeometry>& decoGeoms) const override; 627 private: constructProperties()628 void constructProperties() { 629 constructProperty_display_radius(.004); 630 } 631 }; 632 }; //namespace 633 //============================================================================= 634 //============================================================================= 635 636 #endif //OPENSIM_GEOMETRY_H__ 637