00001 #include "massSpringNode.h"
00002 #include <X3DTK/private/X3D_Coordinate.h>
00003 #include <animal/engine/massSpringEngine.inl>
00004 #include <animal/value.h>
00005 #include <animal/X3DTK/linearX3DTK.h>
00006 #include <animal/engine/AnimalEngineNode.cpp>
00007
00008
00009 namespace X3DTK
00010 {
00011 template class animal::MassSpringSolver< X3DTK::MFVec3f,
00012 X3DTK::MFVec3f,
00013 X3DTK::MFFloat,
00014 X3DTK::MFFloat,
00015 X3DTK::MFInt32
00016 >;
00017 template class animal::MassSpringEngine< X3DTK::MFFloat,
00018 X3DTK::MFVec3f,
00019 X3DTK::MFFloat,
00020 X3DTK::MFInt32,
00021 X3DTK::MFVec3f,
00022 float>;
00023
00024 namespace X3D
00025 {
00026
00027 template class AnimalEngineNode< AMassSpringEngine >;
00028
00029
00030 MassSpringNode::MassSpringNode()
00031 : _coordinate(0)
00032
00033 {
00034
00035
00036
00037
00038 define(Recorder<MassSpringNode>::getTypeName("MassSpringNode"));
00039
00040
00041 define(Recorder<MassSpringNode, MFFloat>::getAttribute("invMasses", &MassSpringNode::_invMassesX3D, MFFloat()));
00042 define(Recorder<MassSpringNode, MFVec3f>::getAttribute("velocities", &MassSpringNode::_velocitiesX3D, MFVec3f()));
00043 define(Recorder<MassSpringNode, MFFloat>::getAttribute("stiffnesses", &MassSpringNode::_stiffnessesX3D, MFFloat()));
00044 define(Recorder<MassSpringNode, MFFloat>::getAttribute("restLengths", &MassSpringNode::_restLengthsX3D, MFFloat()));
00045 define(Recorder<MassSpringNode, MFInt32>::getAttribute("links", &MassSpringNode::_linksX3D, MFInt32()));
00046 define(Recorder<MassSpringNode, SFInt32>::getAttribute("integrationMethod", &MassSpringNode::_method, 0));
00047 define(Recorder<MassSpringNode, SFFloat>::getAttribute("dampingRatio", &MassSpringNode::_dampingRatio, 0.1));
00048 define(Recorder<MassSpringNode, SFFloat>::getAttribute("exponentialDamping", &MassSpringNode::_exponentialDamping, 0.0));
00049 define(Recorder<MassSpringNode, SFVec3f>::getAttribute("gravity", &MassSpringNode::_gravity, SFVec3f(0.0, 0.0, 0.0)));
00050
00051
00052 define(Recorder<MassSpringNode, Coordinate>::getSFNode("Coordinate", &MassSpringNode::_coordinate));
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 }
00063
00064 MassSpringNode::~MassSpringNode()
00065 {
00066 removeParentFromChild(this, _coordinate);
00067 }
00068
00071 void MassSpringNode::init()
00072 {
00073 _invMasses = &_invMassesX3D;
00074 _velocities = &_velocitiesX3D;
00075 _stiffnesses = &_stiffnessesX3D;
00076 _restLengths = &_restLengthsX3D;
00077 _links = &_linksX3D;
00078
00079 if (_exponentialDamping != 0.0) _useExponentialDamping = true;
00080 if (_gravity != SFVec3f(0.0, 0.0, 0.0)) _useGravity=true;
00081
00082
00083 X3D::Coordinate * coord = dynamic_cast < X3D::Coordinate * >(_coordinate);
00084
00085 if (!coord)
00086 {
00087 std::cerr<< "Warning: impossible to init a mass-spring engine: Coordinate node not found"<< std::endl;
00088 return;
00089 }
00090
00091
00092 const MFVec3f * pointsTmp = &(coord->getPoint());
00093 MFVec3f * points = const_cast<MFVec3f *>(pointsTmp);
00094
00095 bool fieldsOK=true;
00096 if( !points )
00097 {
00098 std::cerr<< "MassSpringNode::initEngine : could not read coordinate values" << std::endl;
00099 fieldsOK=false;
00100 }
00101 if( !_velocities )
00102 {
00103 std::cerr<< "MassSpringNode::initEngine : could not read velocit values" << std::endl;
00104 fieldsOK=false;
00105 }
00106 if( !_stiffnesses )
00107 {
00108 std::cerr<< "MassSpringNode::initEngine : could not read stiffness values" << std::endl;
00109 fieldsOK=false;
00110 }
00111 if( !_restLengths )
00112 {
00113 std::cerr<< "MassSpringNode::initEngine : could not read rest length values" << std::endl;
00114 fieldsOK=false;
00115 }
00116 if( !_invMasses )
00117 {
00118 std::cerr<< "MassSpringNode::initEngine : could not read mass values" << std::endl;
00119 fieldsOK=false;
00120 }
00121 else set_useMass(true);
00122 if( !_links )
00123 {
00124 std::cerr<< "MassSpringNode::initEngine : could not read spring indices" << std::endl;
00125 fieldsOK=false;
00126 }
00127 if( !fieldsOK ) return;
00128
00129 if( _invMasses->size() != points->size() )
00130 {
00131 std::cerr<< "Warning: impossible to init a mass-spring engine. In the file .x3d, the masses size is different of the points size."<< std::endl;
00132 return;
00133 }
00134
00135 if( _velocities->size() != points->size() )
00136 {
00137 std::cerr<< "Warning: impossible to init a mass-spring engine. In the file .x3d, the velocities size is different of the points size."<< std::endl;
00138 return;
00139 }
00140
00141 if(_links->size() != 2*_stiffnesses->size())
00142 {
00143 std::cerr<< "Warning: impossible to init a mass-spring engine. In the file .x3d, the indexedSprings size is different of the double of the springStiffness size."<< std::endl;
00144 return;
00145 }
00146
00147 if(_restLengths->size() != _stiffnesses->size())
00148 {
00149 std::cerr<< "Warning: impossible to init a mass-spring engine. In the file .x3d, the restLengths size is different of the springStiffness size."<< std::endl;
00150 return;
00151 }
00152
00153
00154 _points = points;
00155 animal::resize(_initialPoints, animal::size(*_points));
00156 animal::v_eq(_initialPoints, *_points);
00157 animal::resize(_initialVelocities, animal::size(*_velocities));
00158 animal::v_eq(_initialVelocities, *_velocities);
00159
00160
00161 animal::Engine::init();
00162
00163 }
00164
00165 void MassSpringNode::close()
00166 {
00167 _invMassesX3D = *_invMasses;
00168 _velocitiesX3D = *_velocities;
00169 _stiffnessesX3D = *_stiffnesses;
00170 _restLengthsX3D = *_restLengths;
00171 _linksX3D = *_links;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 }
00184 }
00185
00186
00190 void X3DTK::X3D::MassSpringNode::declareOutputs( X3D_X3DNodeList& list )
00191 {
00192 list.push_back(_coordinate);
00193 }
00194
00195
00196
00197
00202 X3DTK::MFVec3f* X3DTK::X3D::MassSpringNode::getCoords()
00203 {
00204 return _points;
00205 }
00206
00207
00212 X3DTK::MFVec3f* X3DTK::X3D::MassSpringNode::getVelocities()
00213 {
00214 return _velocities;
00215 }
00216
00217
00221 X3DTK::MFFloat* X3DTK::X3D::MassSpringNode::getInvMasses()
00222 {
00223 return _invMasses;
00224 }