3DS multi-module linkage manipulator is used as an example.
Now we want to achieve mechanical arm movement. An excavator is used as an example:
We divide the excavator into several parts.
1. chassis, 2. Convertible body, 3. Arm, 4. forearm, 5. Skip.
Process:
1. Layer by name
2. Find the rotation axis of each layer
3. Calculate each rotation angle
4. Draw Layers
Step 2. Layer by name:
Vector
Obj1vec, obj2vec, obj3vec, obj4vec, obj5vec; // five-layer Object Name 1, chassis, 2, convertible body, 3, arm, 4, forearm, 5, dump. GLfloat spin 2 = 0, spin 3 = 0, spin 4 = 0, spin 5 = 0; // four-layer Rotation
// Name layer void initName () {unsigned int e; // The first layer object chassis (excluding all movable parts) for (unsigned int I = 0; I
2nd. Find the rotation axis of each layer
Float scaleNum = 1.0f; // unit length for ranging purposes/* axis of rotation (Auxiliary) */void huaxyz () {// first // draw coordinate system // xt1 = 0; // to the right + // yt1 = scaleNum * 20; // up + // zt1 = scaleNum * 19; // outside the screen + 19 glTranslatef (xt1, 0.0f, 0.0f ); // x1glTranslatef (0.0f, yt1, 0.0f); // y1glTranslatef (0.0f, 0.0f, zt1); // z1 // 1. draw the coordinate axis (straight line) glColor3f (0.0, 0.0, 1.0); // --> Red GLfloat curSizeLine = 5; // glLineWidth (curSizeLine); glBegin (GL_LINES ); // X axis trim (-18000000f, 0.0f, 0.0f); glVertex3f (18000000f, 0.0f, 0.0f); glEnd (); glBegin (GL_LINES); // y axis glVertex3f (0.0f, -18000000f, 0.0f); glVertex3f (0.0f, 18000000f, 0.0f); glEnd (); glBegin (GL_LINES); // Z axis glVertex3f (0.0f, 0.0f,-18000000f ); glVertex3f (0.0f, 0.0f, 18000000f); glEnd (); // second, third, fourth, omitted}
Here we need to adjust it slowly.
Is to adjust the Axis Position
3rd. Calculate each rotation angle
Spin2+=0.3; if( Spin2 > 360 )Spin2 -= 360;
Only one
4th. Draw Layers
// Display the 3ds Model void drawModel (t3DModel Model, bool touming, bool outTex ){... for details, see the original article // traverse all objects in the Model for (int I = 0; I <Model. numOfObjects; I ++) {// obtain the currently displayed object t3DObject * pObject; // ==================================== int count1 = obj1vec. size (); int count2 = obj2vec. size (); int count3 = obj3vec. size (); int count4 = obj4vec. size (); int count5 = obj5vec. size (); if (I
Running diagram:
Complete code:
// 3DS excavator action (3ds model with texture textures, + illumination + virtual ball rotation) # define name3DS "Data/3ds/wj.3DS" // # include "CLoad3DS1. cpp" vector
Obj1vec, obj2vec, obj3vec, obj4vec, obj5vec; // five-layer Object Name 1, chassis, 2, convertible body, 3, arm, 4, forearm, 5, dump. GLfloat spin 2 = 0, spin 3 = 0, spin 4 = 0, spin 5 = 0; // The number of four-layer rotation float scaleNum = 1.0f; // The unit length for ranging GLfloat xt1 = 0.0, yt1 = 0.0, zt1 = 0.0f; // float rquad = 0.0; // void huaxyz (); // display the 3ds Model void drawModel (t3DModel Model, bool touming, bool outTex) {if (touming) {glable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f (0.5, 1 );} // traverse all objects in the Model for (int I = 0; I <Model. numOfObjects; I ++) {// obtain the currently displayed object t3DObject * pObject; // ==================================== int count1 = obj1vec. size (); int count2 = obj2vec. size (); int count3 = obj3vec. size (); int count4 = obj4vec. size (); int count5 = obj5vec. size (); if (I
BHasTexture) {// enable the texture ing GL_TEXTURE_2D; glBindTexture (GL_TEXTURE_2D, Model. texture [pObject-> materialID]);} else {// disable the texture ing glDisable (GL_TEXTURE_2D); glColor3ub (255,255,255);} if (I
NumOfFaces; j ++) {// traverse all vertices of a triangle for (int whichVertex = 0; whichVertex <3; whichVertex ++) {// obtain the index int index = pObject-> pFaces [j] for each vertex. vertIndex [whichVertex]; // returns the regular vector glNormal3f (pObject-> pNormals [index]. x, pObject-> pNormals [index]. y, pObject-> pNormals [index]. z); // if the object has a texture if (pObject-> bHasTexture) {// determine whether there is a UVW texture coordinate if (pObject-> pTexVerts) {glColor3f (1.0, 1.0, 1.0); glTexCoord2f (pObject-> pTexVerts [index]. x, pObject-> pTexVerts [index]. y) ;}} else {if (Model. pMaterials. size () & pObject-> materialID> = 0) {BYTE * pColor = Model. pMaterials [pObject-> materialID]. color; glColor3ub (pColor [0], pColor [1], pColor [2]) ;}} glVertex3f (pObject-> pVerts [index]. x, pObject-> pVerts [index]. y, pObject-> pVerts [index]. z) ;}} glEnd (); // draw end} glPopMatrix (); // restore the original location // huaxyz (); if (touming) glDisable (GL_BLEND );} # include "ArcBall. cpp "const GLfloat lightPosition [] = {10.0,-10.0, 10.0, 0.0}; // The Position of the light source in an infinite distance + direction const GLfloat whiteLight [] = {0.8, 0.8, 0.8, 1.0}; GLfloat matSpecular [] = {0.3, 0.3, 0.3, 1.0}; // GLfloat matShininess [] = {20.0 }; GLfloat matEmission [] = {0.3, 0.3, 0.3, 1.0}; GLfloat spin = 0; GLint width = 600; GLint height = 480; CLoad3DS * gothicLoader = new (CLoad3DS ); t3DModel gothicModel; float gothicTrans [10] = {0, 0,-30, // indicates the position 0, 0, 0, 0 in the world matrix, // indicates the xyz magnification of 0, 0, 0, 0 // indicates rotation}; // initialization, must use the global variable method, cannot use newArcBallT arcBall (600366f, 400366f); ArcBallT * ArcBall = & arcBall; // new ArcBallT (6000000f, 4000000f); // & arcBall; char * filename3ds = name3DS; // move void move (int x, int y) {ArcBall-> MousePt. s. X = x; ArcBall-> MousePt. s. Y = y; ArcBall-> upstate (); glupostredisplay () ;}// click void mouse (int button, int state, int x, int y) {if (button = maid) {ArcBall-> isClicked = true; move (x, y );} else if (button = maid-> isClicked = false; else if (button = maid) {ArcBall-> isRClicked = true; move (x, y);} else if (button = fig-> isRClicked = false; arcBall-> upstate (); glupostredisplay () ;}// layer the name into void initName () {unsigned int e; // The first layer object chassis (excluding all movable parts) for (unsigned int I = 0; I
X; xmin = (t
Xmax )? T: xmax; t = pVerts-> y; ymin = (t
Ymax )? T: ymax; t = pVerts-> z; zmin = (t
Zmax )? T: zmax; pVerts ++; // next vertex} // display the object name printf ("Object % d name: % s \ n", I, gothicModel. pObject [I]. strName);} // display the minimum maximum value printf ("xmin: % f, xmax: % f \ n", xmin, xmax); printf ("ymin: % f, ymax: % f \ n ", ymin, ymax); printf (" zmin: % f, xmax: % f \ n ", zmin, zmax); printf (" width (x difference): % f, \ n ", xmax-xmin); printf (" height (y difference): % f, \ n ", ymax-ymin ); printf ("depth (z difference): % f, \ n", zmax-zmin); float xm, ym, zm, B; xm = xmax-xmin; ym = ymax-ymin; zm = zmax-zmin; float max3 = max (xm, Ym), zm); B = 1.0/max3; scaleNum = max3/100; // a unit of 1 printf ("magnification: % f, \ n ", b); printf ("1 Unit: % f \ n", scaleNum); gothicTrans [3] = gothicTrans [4] = gothicTrans [5] = B; // set the magnification // move to the center of the screen gothicTrans [0] =-(xmin + (xmax-xmin)/2) * B; gothicTrans [1] =-(ymin + (ymax-ymin)/2) * B; gothicTrans [2] =-(zmin + (zmax-zmin)/2) * b-20;} void init () {gothicLoader-> Import3DS (& gothicModel, filename3ds); // import the model, the second parameter is the path of the 3ds file, zhong (); initName (); // modulo Type object display layer sorting glClearColor (0.3, 0.3, 0.3, 1.0); glClearDepth (1.0); glShadeModel (GL_SMOOTH); glable (GL_LIGHTING ); // enable the glable (GL_LIGHT0) function of the illumination processing function; // use The 0th illumination GL_DEPTH_TEST; glMatrixMode (GL_MODELVIEW); // operate glLoadIdentity () on the model visual matrix (); // move the coordinate origin to the center gluPerspective (3.0f, (GLfloat) width/(GLfloat) height, 0.1f, 100366f); glLightfv (GL_LIGHT0, GL_POSITION, lightPosition ); // The Position of the light source. // GL_DIFFUSE: the light emitted by the light source. The light intensity (color) glLightfv (GL_LIGHT0, GL_DIFFUSE, whiteLight) is obtained after diffuse reflection on the rough surface ); // GL_SPECULAR: The intensity (color) of the light emitted by the light source after the light is reflected on the smooth surface ). GlLightfv (GL_LIGHT0, GL_SPECULAR, whiteLight);} void display () {glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the color and depth buffer glMatrixMode (GL_PROJECTION ); // perform glLoadIdentity () on the projection matrix; // move the coordinate origin to the center glMatrixMode (GL_MODELVIEW); // perform glPushMatrix () on the model visual matrix; glRotatef (spin, 0.0, 1.0, 0.0); // set the material glMaterialfv (GL_FRONT, GL_SPECULAR, matSpecular); // set the glMaterialfv (GL_FRONT, GL_SHININESS, matShininess); // The Mirror Index GlMaterialfv (GL_FRONT, Rack, matEmission); // self-emitting changeObject (gothicTrans); // ----- trackball ---------- start glScalef (ArcBall-> zoomRate, ArcBall-> zoomRate, arcBall-> zoomRate); // 2. scale glMultMatrixf (ArcBall-> Transform. m); // 3. rotate // ----- trackball ---------- end drawModel (gothicModel, true, false); // huaxyz (); glPopMatrix (); glFlush ();} void keyboardFunc (unsigned char key, int x, int y) {switch (key) {case 'A': zt1 + = 80; break; case 'D': zt1-= 80; break;} printf ("zt1: % f \ n", zt1); // if (spin <360) // spin + = 360; // else if (spin> = 360) // spin-= 360; // fig ();} void SpinDisplay () {Spin2 + = 0.3; if (Spin2> 360) Spin2-= 360; static int Spin3 T = 1; // in the direction of Spin3, if (Spin3 T = 1) Spin3 + = 0.3; elseSpin3-= 0.3; if (Spin3> 60) spin 3 T =-1; if (Spin3 <1) spin 3 T = 1; glupostredisplay ();} int main (int argc, char * argv []) {if (ar Gc = 2) filename3ds = argv [1]; fig (& argc, argv); fig mode (Fig | fig); fig (width, height ); gluinitwindowposition (150,150); glucreatewindow ("3DS excavator action Demo"); gludisplayfunc (display); // glukeyboardfunc (keyboardFunc); init (); glumousefunc (mouse ); // register a mouse event. Glumotionfunc (move); // register the mobile event glutIdleFunc (SpinDisplay); // register and rotate the glumainloop (); return EXIT_SUCCESS;}/* locate the rotation axis (secondary) */void huaxyz () {// first // draw the coordinate system float xt1 =-scaleNum * 4.6; // + float yt1 =-scaleNum * 92.4 to the right; // up + float zt1 =-scaleNum * 14.6; // out-of-screen + glTranslatef (xt1, 0.0f, 0.0f); // x1glTranslatef (0.0f, yt1, 0.0f ); // move the y1glTranslatef (0.0f, 0.0f, zt1) on the Y axis; // z1 /// 1. draw the coordinate axis (straight line) glColor3f (1.0, 0.0, 0.0); // --> Red GLfloat curSizeLine = 5; // glLineWidth (curSizeLine); // glBegin (GL_LINES ); // X axis // glVertex3f (-8000000f, 0.0f, 0.0f); // glVertex3f (8000000f, 0.0f, 0.0f); // glEnd (); glBegin (GL_LINES ); // y-axis glVertex3f (0.0f,-8000000f, 0.0f); glVertex3f (0.0f, 8000000f, 0.0f); glEnd (); // glBegin (GL_LINES ); // Z axis // glVertex3f (0.0f, 0.0f,-8000000f); // glVertex3f (0.0f, 0.0f, 8000000f); // glEnd (); // second ============================================== ============== float xt2 = scaleNum * 7.1, zt2 = scaleNum * 5.3; glTranslatef (xt2, 0.0f, zt2); // 2. draw the coordinate axis (straight line) glColor3f (0.0, 1.0, 0.0); // --> green glBegin (GL_LINES); // X axis glVertex3f (-8001_f, 0.0f, 0.0f ); glVertex3f (8000000f, 0.0f, 0.0f); glEnd (); // glBegin (GL_LINES); // y axis // glVertex3f (0.0f,-8000000f, 0.0f ); // glVertex3f (0.0f, 8000000f, 0.0f); // glEnd (); // glBegin (GL_LINES); // Z axis // glVertex3f (0.0f, 0.0f, -8000000f); // glVertex3f (0.0f, 0.0f, 8000000f); // glEnd (); /// third ================================================= ================== yt1 = scaleNum * 35; // up + zt1 = scaleNum * 45; // to the outside of the screen + glTranslatef (0.0f, yt1, 0.0f); // move the Y axis y1glTranslatef (0.0f, 0.0f, zt1 ); // z1 // 2. draw the coordinate axis (straight line) glColor3f (0.0, 0.0, 1.0); // --> blue glBegin (GL_LINES); // X axis glVertex3f (-8001_f, 0.0f, 0.0f ); glVertex3f (8000000f, 0.0f, 0.0f); glEnd (); // glBegin (GL_LINES); // y axis // glVertex3f (0.0f,-8000000f, 0.0f ); // glVertex3f (0.0f, 8000000f, 0.0f); // glEnd (); // glBegin (GL_LINES); // Z axis // glVertex3f (0.0f, 0.0f, -8000000f); // glVertex3f (0.0f, 0.0f, 8000000f); // glEnd (); /// fourth ================================================= ================== yt1 =-scaleNum * 23; // up + zt1 = scaleNum * 16; // to the outside of the screen + glTranslatef (0.0f, yt1, 0.0f); // move the Y axis y1glTranslatef (0.0f, 0.0f, zt1 ); // z1 // 2. draw the coordinate axis (straight line) glColor3f (1.0, 0.0, 1.0); // --> purple glBegin (GL_LINES); // X axis glVertex3f (-8001_f, 0.0f, 0.0f ); glVertex3f (8000000f, 0.0f, 0.0f); glEnd (); // glBegin (GL_LINES); // y axis // glVertex3f (0.0f,-8000000f, 0.0f ); // glVertex3f (0.0f, 8000000f, 0.0f); // glEnd (); // glBegin (GL_LINES); // Z axis // glVertex3f (0.0f, 0.0f, -8000000f); // glVertex3f (0.0f, 0.0f, 8000000f); // glEnd ();}
Because the hydraulic drive is not implemented, this Part has been removed from the full code and is not displayed (see the code above)