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
00026 #include "arch.h"
00027
00028 #include <Inventor/nodes/SoSeparator.h>
00029 #include <Inventor/nodes/SoCoordinate3.h>
00030 #include <Inventor/nodes/SoIndexedFaceSet.h>
00031 #include <Inventor/nodes/SoMaterial.h>
00032 #include <Inventor/nodes/SoGroup.h>
00033 #include <Inventor/nodes/SoTransform.h>
00034 #include <Inventor/nodes/SoTranslation.h>
00035
00036 #include "body.h"
00037 #include "graspitGUI.h"
00038 #include "ivmgr.h"
00039 #include "world.h"
00040
00041 DynamicBody *rightBase;
00042
00043 Body* createSupport(double size, double thickness, World *world)
00044 {
00045 Body *body = new Body(world,"Support");
00046
00047
00048 SbVec3f *points = new SbVec3f[8];
00049
00050
00051
00052 double z = thickness;
00053
00054 points[3].setValue( size, size, z);
00055 points[2].setValue(-size, size, z);
00056 points[1].setValue(-size,-size, z);
00057 points[0].setValue( size,-size, z);
00058
00059 points[7].setValue( size, size,-z);
00060 points[6].setValue(-size, size,-z);
00061 points[5].setValue(-size,-size,-z);
00062 points[4].setValue( size,-size,-z);
00063
00064 int32_t c[5*6] = { 3, 2, 1, 0, -1,
00065 4, 5, 6, 7, -1,
00066 1, 5, 4, 0, -1,
00067 2, 6, 5, 1, -1,
00068 3, 7, 6, 2, -1,
00069 4, 7, 3, 0, -1 };
00070
00071 SoCoordinate3 *coords = new SoCoordinate3;
00072 coords->point.setValues( 0, 8, points );
00073 SoIndexedFaceSet *ifs = new SoIndexedFaceSet;
00074 ifs->coordIndex.setValues(0, 5*6, c);
00075
00076 body->getIVGeomRoot()->addChild(coords);
00077 body->getIVGeomRoot()->addChild(ifs);
00078 body->setMaterial( world->getMaterialIdx("stone") );
00079 body->addIVMat();
00080 return body;
00081 }
00082
00083
00084 GraspableBody* create_block(double inner_radius, double outer_radius, double thickness, int n_blocks, World *world)
00085 {
00086 double block_span = 3.14159 / n_blocks;
00087 double theta = block_span / 2;
00088 double radius = (inner_radius + outer_radius) / 2;
00089
00090 double icx = inner_radius * cos(theta) - radius;
00091 double icz = inner_radius * sin(theta);
00092
00093 double ocx = outer_radius * cos(theta) - radius;
00094 double ocz = outer_radius * sin(theta);
00095
00096 double y = thickness / 2;
00097
00098 GraspableBody *body = new GraspableBody(world,"Original Block");
00099
00100
00101 SbVec3f *points = new SbVec3f[8];
00102
00103
00104
00105 points[0].setValue( icx, y, -icz);
00106 points[1].setValue( icx, y, icz);
00107 points[2].setValue( icx,-y, icz);
00108 points[3].setValue( icx,-y, -icz);
00109
00110 points[4].setValue( ocx, y, -ocz);
00111 points[5].setValue( ocx, y, ocz);
00112 points[6].setValue( ocx,-y, ocz);
00113 points[7].setValue( ocx,-y, -ocz);
00114
00115 int32_t c[5*6] = { 3, 2, 1, 0, -1,
00116 4, 5, 6, 7, -1,
00117 1, 5, 4, 0, -1,
00118 2, 6, 5, 1, -1,
00119 3, 7, 6, 2, -1,
00120 4, 7, 3, 0, -1 };
00121
00122 SoCoordinate3 *coords = new SoCoordinate3;
00123 coords->point.setValues( 0, 8, points );
00124 SoIndexedFaceSet *ifs = new SoIndexedFaceSet;
00125 ifs->coordIndex.setValues(0, 5*6, c);
00126
00127 body->getIVGeomRoot()->addChild(coords);
00128 body->getIVGeomRoot()->addChild(ifs);
00129 body->setMaterial( world->getMaterialIdx("stone") );
00130 body->addIVMat();
00131
00132 double density = 2 * 1.0e-3;
00133 double volume = thickness * 0.5 * block_span * (outer_radius * outer_radius - inner_radius * inner_radius);
00134 double mass = density * volume;
00135 body->setMass(mass);
00136 body->setMaxRadius(body->computeDefaultMaxRadius());
00137 double I[9];
00138 position CoG;
00139 body->computeDefaultMassProp(CoG, I);
00140 body->setCoG(CoG);
00141 body->setInertiaMatrix(I);
00142 fprintf(stderr,"Volume %f and mass %f\n",volume, mass);
00143
00144 return body;
00145 }
00146
00147 void create_arch(World *world, double inner_radius, double outer_radius, double thickness, int n_blocks, bool add_supports)
00148 {
00149 fprintf(stderr,"Building arch: inner radius %f, outer radius %f, thickness %f, %d blocks, %d add_supports\n",
00150 inner_radius, outer_radius, thickness, n_blocks, add_supports);
00151
00152 GraspableBody* block = create_block(inner_radius, outer_radius, thickness, n_blocks, world);
00153
00154 block->addToIvc();
00155
00156 world->toggleCollisions(false, block);
00157
00158 transf blockTran,blockRot;
00159 double block_span = 3.14159 / n_blocks;
00160 double theta = block_span / 2;
00161 double radius = (inner_radius + outer_radius) / 2;
00162 for (int i=0; i<n_blocks; i++) {
00163 QString name("Block "),id;
00164 name.append(id.setNum(i));
00165 GraspableBody *addBlock = new GraspableBody(world,name.latin1());
00166 addBlock->cloneFrom(block);
00167 world->addBody(addBlock);
00168
00169 Quaternion r( theta*(2*i+1) , vec3(0,-1,0) );
00170
00171 vec3 t( radius+0.1 , 0, 0);
00172
00173 blockRot.set(r, vec3(0,0,0) );
00174 blockTran.set(Quaternion::IDENTITY, t);
00175
00176 addBlock->setTran( blockTran * blockRot);
00177
00178 if (i==n_blocks-1)
00179 rightBase = addBlock;
00180 }
00181 if (add_supports) {
00182 Body* leftSupport = createSupport(0.9 * radius,50,world);
00183 leftSupport->setName( QString("Left Support") );
00184 Body* rightSupport = createSupport(0.9 * radius,50,world);
00185 rightSupport->setName( QString("Right Support") );
00186
00187 leftSupport->addToIvc();
00188 rightSupport->addToIvc();
00189
00190 vec3 t( radius+1, 0, -(50+Contact::THRESHOLD));
00191 blockTran.set( Quaternion::IDENTITY, t);
00192 leftSupport->setTran( blockTran );
00193 world->addBody(leftSupport);
00194
00195 t.set( -radius-1, 0, -(50+Contact::THRESHOLD));
00196 blockTran.set( Quaternion::IDENTITY, t);
00197 rightSupport->setTran( blockTran );
00198 world->addBody(rightSupport);
00199 }
00200 }
00201
00202 void archSnapshot()
00203 {
00204 static int steps = 0;
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 if (steps%10 == 0) {
00215 fprintf(stderr,"Set velocity\n");
00216 double newVel[6];
00217 for (int i=0; i<6; i++)
00218 newVel[i] = rightBase->getVelocity()[i];
00219 newVel[0] -= 100;
00220 rightBase->setVelocity(newVel);
00221 }
00222 steps++;
00223 }