00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <physics/Torus>
00026 #include <physics/Material>
00027 #include <gfx/VisualTriangles>
00028
00029 #include <osg/Group>
00030 #include <osg/Geode>
00031 #include <osg/LOD>
00032
00033
00034 using physics::Torus;
00035 using physics::MassProperties;
00036 using physics::CollisionModel;
00037
00038 using gfx::Segment3;
00039 using gfx::VisualTriangles;
00040
00041 using osg::Node;
00042 using osg::Group;
00043 using osg::Geode;
00044 using osg::LOD;
00045 using osg::Vec3;
00046 using osg::Vec2;
00047
00048
00049 Torus::Torus(Real innerRadius, Real outerRadius)
00050 : _innerRadius(innerRadius), _outerRadius(outerRadius)
00051 {
00052 }
00053
00054 Torus::Torus(const Torus& t)
00055 : _innerRadius(t._innerRadius), _outerRadius(t._outerRadius)
00056 {
00057 }
00058
00059 Torus::~Torus()
00060 {
00061 }
00062
00063
00064 const MassProperties& Torus::getMassProperties(ref<const Material> material) const
00065 {
00066 if (massPropertiesCached && (density == material->density()))
00067 return massProperties;
00068
00069 density = material->density();
00070 massProperties = MassProperties(VisualTriangles(*this),material);
00071
00072 massPropertiesCached = true;
00073 return massProperties;
00074 }
00075
00076
00077 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const Point3& p) const
00078 {
00079 Unimplemented;
00080 }
00081
00082
00083 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const gfx::Segment3& s) const
00084 {
00085 Unimplemented;
00086 }
00087
00088
00089 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const gfx::Triangle3& tri) const
00090 {
00091 Unimplemented;
00092 }
00093
00094
00095 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const gfx::Quad3& q) const
00096 {
00097 Unimplemented;
00098 }
00099
00100
00101 Segment3 Torus::shortestSegmentBetween(const base::Transform& t1, ref<const Shape> s, const base::Transform& t2) const
00102 {
00103 Unimplemented;
00104 }
00105
00106
00107
00108 osg::Node* Torus::createOSGTorus(Visual::Attributes visualAttributes,
00109 Int sides, Int rings) const
00110 {
00111 bool onlyVerts = ((visualAttributes & Visual::VerticesOnly) != 0);
00112
00113 SInt i, j;
00114 Real theta, phi, theta1;
00115 Real cosTheta, sinTheta;
00116 Real cosTheta1, sinTheta1;
00117 Real ringDelta, sideDelta;
00118
00119 Real cosPhi, sinPhi, dist;
00120
00121 sideDelta = 2.0 * consts::Pi / Real(sides);
00122 ringDelta = 2.0 * consts::Pi / Real(rings);
00123
00124 theta = 0.0;
00125 cosTheta = 1.0;
00126 sinTheta = 0.0;
00127
00128 array<Vec3>& coords = *new array<Vec3>(rings*(sides*2+2));
00129 array<Vec3>& normals = *new array<Vec3>(rings*(sides*2+2));
00130
00131 array<int>& lengths = *new array<int>(rings);
00132 for(Int i=0; i<rings; i++)
00133 lengths[i] = sides*2+2;
00134
00135 Int index=0;
00136
00137 for (i = rings - 1; i>= 0;i--) {
00138 theta1 = theta + ringDelta;
00139 cosTheta1 = Math::cos(theta1);
00140 sinTheta1 = Math::sin(theta1);
00141
00142 phi = (sides+1)*sideDelta;
00143 for (j = sides; j>=0; j--) {
00144 phi = phi - sideDelta;
00145 cosPhi = Math::cos(phi);
00146 sinPhi = Math::sin(phi);
00147 dist = outerRadius() + (innerRadius() * cosPhi);
00148
00149 if (!onlyVerts) {
00150 normals[index] = Vec3(cosTheta1 * cosPhi, sinPhi, -sinTheta1 * cosPhi);
00151 normals[index+1] = Vec3(cosTheta * cosPhi, sinPhi, -sinTheta * cosPhi);
00152 }
00153 coords[index] = Vec3(cosTheta1 * dist, innerRadius() * sinPhi, -sinTheta1 * dist);
00154 coords[index+1] = Vec3(cosTheta * dist, innerRadius() * sinPhi, -sinTheta * dist);
00155 index+=2;
00156
00157 }
00158 theta = theta1;
00159 cosTheta = cosTheta1;
00160 sinTheta = sinTheta1;
00161 }
00162
00163
00164 GeoSet* torus = new GeoSet();
00165 torus->setPrimType(GeoSet::QUAD_STRIP);
00166 torus->setNumPrims(rings);
00167 torus->setCoords(coords.c_array());
00168 torus->setPrimLengths(lengths.c_array());
00169 if (!onlyVerts) {
00170 torus->setNormals(normals.c_array());
00171 torus->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
00172
00173
00174 }
00175
00176 osg::Geode* geode = new osg::Geode();
00177 geode->addDrawable(torus);
00178
00179 return geode;
00180 }
00181
00182
00183 osg::Node* Torus::createOSGVisual(Visual::Attributes visualAttributes) const
00184 {
00185 if ((node!=0) && (attributes==visualAttributes))
00186 return &(*node);
00187
00188 Real ri = Math::maximum(1.0,innerRadius()*2.0);
00189 Real ro = Math::maximum(1.0,outerRadius()*2.0);
00190
00191 osg::Node* node0 = createOSGTorus(visualAttributes, Int(22*ri), Int(22*ro));
00192 osg::Node* node1 = createOSGTorus(visualAttributes, Int(16*ri), Int(16*ro));
00193 osg::Node* node2 = createOSGTorus(visualAttributes, Int(8*ri), Int(12*ro));
00194 osg::Node* node3 = createOSGTorus(visualAttributes, 6, 8);
00195
00196 osg::LOD* lod = new osg::LOD();
00197 lod->setName("Torus");
00198 lod->addChild(node0);
00199 lod->addChild(node1);
00200 lod->addChild(node2);
00201 lod->addChild(node3);
00202
00203 lod->setRange(0,0,2.0);
00204 lod->setRange(1,2.0,16.0);
00205 lod->setRange(2,16.0,120.0*ro);
00206 lod->setRange(3,120.0*ro,consts::Infinity);
00207
00208 if (!(visualAttributes & Visual::ShowAxes))
00209 node = lod;
00210 else {
00211 Group* group = new Group();
00212 group->addChild( lod );
00213 group->addChild( createOSGAxes(base::Dimension3(outerRadius(),innerRadius(),outerRadius())*2.0) );
00214 node = group;
00215 }
00216
00217 attributes = visualAttributes;
00218 return &(*node);
00219 }
00220
00221
00222
00223 base::ref<CollisionModel> Torus::getCollisionModel(CollisionModel::CollisionModelType modelType) const
00224 {
00225 if ((collisionModel!=0) &&
00226 ((this->modelType==modelType) || (modelType==CollisionModel::AnyModel)))
00227 return collisionModel;
00228
00229 collisionModel = Shape::getCollisionModel(modelType);
00230 this->modelType=modelType;
00231
00232 return collisionModel;
00233 }
00234
00235 void Torus::serialize(base::Serializer& s)
00236 {
00237 s(_innerRadius)(_outerRadius);
00238
00239 if (s.isInput()) {
00240 massPropertiesCached = false;
00241 node = 0;
00242 collisionModel = ref<CollisionModel>(0);
00243 }
00244 }
00245