VISH
0.2
|
An example of a rotating gear, as derived from an Qt example.
#include <stdio.h> #include <ocean/GLvish/VGLRenderObject.hpp> #include <ocean/GLvish/Pickable.hpp> #include <ocean/plankton/VCreator.hpp> #include <ocean/plankton/VTime.hpp> #include <ocean/GLvish/BoundingBox.hpp> #include <stdio.h> using namespace Wizt; namespace { class GearExample : public Wizt::VGLRenderObject, public Pickable { struct AccelState : State { double last_t; float phi0, phi1, phi2; float current_speed, target_speed; }; virtual void render(VGLRenderContext&Context) const; public: TypedSlot<int> Teeth, Speed; GearExample(const string&name, int p, const RefPtr<VCreationPreferences>&VP) : VGLRenderObject(name, p, VP) , Teeth(this, "teeth", 10) , Speed(this, "speed", 10) { // Define speed as a parameter local to each viewer context Speed->Localize(); // Explicit setting of a bounding box to this object // myBBox() = new BoundingBox(point(-1,-1,-1), point(1,1,1) ); } ~GearExample() {} override bool request(VRequest&R, double precision, const WeakVObjectPtr&ImmediateRequestor, const WeakVObjectPtr&RootRequestor) { age(R).touch(); return VGLRenderObject::request(R,precision, ImmediateRequestor, RootRequestor); } void GearRender(VGLRenderContext&Context, const GLfloat red[4]) const; }; /* * Draw a gear wheel. You'll probably want to call this function when * building a display list since we do a lot of trig here. --> should do this via display lists and transformation matrix! * * Input: inner_radius - radius of hole at center * outer_radius - radius at center of teeth * width - width of gear * teeth - number of teeth * tooth_depth - depth of tooth */ static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth, float offset ) { GLint i; GLfloat r0, r1, r2; GLfloat angle, da; GLfloat u, v, len; r0 = inner_radius; r1 = outer_radius - tooth_depth/2.0; r2 = outer_radius + tooth_depth/2.0; const double pi = 3.14159264; da = 2.0*pi / teeth / 4.0; glShadeModel( GL_SMOOTH ); glNormal3f( 0.0, 0.0, 1.0 ); /* draw front face */ glBegin( GL_QUAD_STRIP ); for (i=0;i<=teeth;i++) { angle = i * 2.0*pi / teeth + offset; glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 ); glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 ); glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 ); glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 ); } glEnd(); /* draw front sides of teeth */ glBegin( GL_QUADS ); da = 2.0*pi / teeth / 4.0; for (i=0;i<teeth;i++) { angle = i * 2.0*pi / teeth + offset; glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 ); glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 ); glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 ); glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 ); } glEnd(); glNormal3f( 0.0, 0.0, -1.0 ); /* draw back face */ glBegin( GL_QUAD_STRIP ); for (i=0;i<=teeth;i++) { angle = i * 2.0*pi / teeth + offset; glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 ); glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 ); glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 ); glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 ); } glEnd(); /* draw back sides of teeth */ glBegin( GL_QUADS ); da = 2.0*pi / teeth / 4.0; for (i=0;i<teeth;i++) { angle = i * 2.0*pi / teeth + offset; glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 ); glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 ); glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 ); glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 ); } glEnd(); /* draw outward faces of teeth */ glBegin( GL_QUAD_STRIP ); for (i=0;i<teeth;i++) { angle = i * 2.0*pi / teeth + offset; glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 ); glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 ); u = r2*cos(angle+da) - r1*cos(angle); v = r2*sin(angle+da) - r1*sin(angle); len = sqrt( u*u + v*v ); u /= len; v /= len; glNormal3f( v, -u, 0.0 ); glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 ); glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 ); glNormal3f( cos(angle), sin(angle), 0.0 ); glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 ); glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 ); u = r1*cos(angle+3*da) - r2*cos(angle+2*da); v = r1*sin(angle+3*da) - r2*sin(angle+2*da); glNormal3f( v, -u, 0.0 ); glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 ); glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 ); glNormal3f( cos(angle), sin(angle), 0.0 ); } glVertex3f( r1*cos(offset), r1*sin(offset), width*0.5 ); glVertex3f( r1*cos(offset), r1*sin(offset), -width*0.5 ); glEnd(); glShadeModel( GL_SMOOTH ); /* draw inside radius cylinder */ glBegin( GL_QUAD_STRIP ); for (i=0;i<=teeth;i++) { angle = i * 2.0*pi / teeth + offset; glNormal3f( -cos(angle), -sin(angle), 0.0 ); glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 ); glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 ); } glEnd(); } void GearExample::render(VGLRenderContext&Context) const { //static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 }; static GLfloat red[4] = {0.1, 0.1, 0.1, 1.0 }; //static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 }; //static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 }; //static GLfloat white[4] = {0.8, 0.8, 0.9, 1.0 }; resetBBox(Context); GearRender(Context, red); closeBBox(Context); } void GearExample::GearRender(VGLRenderContext&Context, const GLfloat red[4]) const { //static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 }; static GLfloat Red[4] = {0.9, 0.1, 0.1, 1.0 }; static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 }; static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 }; //static GLfloat white[4] = {0.8, 0.8, 0.9, 1.0 }; //puts("void GearExample::GearRender(VGLRenderContext&Context, const GLfloat red[4]) "); //fprintf(stderr,"void GearExample::GearRender(VGLRenderContext&Context, const GLfloat red[4]) "); fflush(stderr); // glPushAttrib(GL_ALL_ATTRIB_BITS); // glDisable(GL_CULL_FACE ); glEnable(GL_CULL_FACE ); glEnable( GL_LIGHTING ); // glEnable( GL_LIGHT0 ); glEnable( GL_DEPTH_TEST ); glEnable( GL_COLOR_MATERIAL ); glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); int speed = 100; /* This is the operator interface to retrieve values from a slot! */ Speed << Context >> speed; RefPtr<AccelState> myState = getState(Context); if (!myState) { myState = new AccelState(); setState(Context, myState); myState->target_speed = myState->current_speed = speed; myState->phi0 = myState->phi1 = myState->phi2 = 0; myState->last_t = Context.time.seconds; } else myState->target_speed = speed; if (myState->current_speed < myState->target_speed) myState->current_speed+=2; if (myState->current_speed > myState->target_speed) myState->current_speed-=2; float omega = myState->current_speed / 50.0; double t = Context.time.seconds, dt = t - myState->last_t; myState->last_t = t; //printf("time: %20.20lg %lg %20.20lg\n", t, dt, myState->last_t); myState->phi0 += omega*dt; myState->phi1 += -2.0*omega*dt; myState->phi2 +=0.566*omega*dt; int teeth = 10; Teeth << Context >> teeth; embrace( Context, point(-3,-2,0) + tvector3(4.0, 4.0, 1.1) ); embrace( Context, point(-3,-2,0) - tvector3(4.0, 4.0, 1.1) ); SubObjectBegin(Context); glPushMatrix(); glTranslatef( -3.0, -2.0, 0.0 ); vglColor4fv(Context, Red, 0.4); glColor4fv(Red); gear( 1.0, 4.0, 1.0, 17+teeth, 1.1, myState->phi0); glPopMatrix(); embrace( Context, point(3.1,-2,0) + tvector3(2.0, 2.0, 0.7) ); embrace( Context, point(3.1,-2,0) - tvector3(2.0, 2.0, 0.7) ); SubObjectBegin(Context); glPushMatrix(); glTranslatef( 3.1, -2.0, 0.0 ); vglColor4fv(Context, green, 0.4); gear( 0.5, 2.0, 2.0, 10+teeth, 0.7, myState->phi1); glPopMatrix(); embrace( Context, point(-3.1, 2.2,-5.8) + tvector3(6.0, 1.2, 6.0) ); embrace( Context, point(-3.1, 2.2,-5.8) - tvector3(6.0, 1.2, 6.0) ); SubObjectBegin(Context); glPushMatrix(); glTranslatef( -3.1, 2.2, -5.8 ); glRotatef( 90.0, 1.0, 0.0, 0.0 ); vglColor4fv(Context, blue, 0.4); gear( 1.3, 6.0, 0.3, 30+teeth, 1.2, myState->phi2); glPopMatrix(); closeBBox( Context ); } static Ref<VCreator<GearExample> > gearCreator("Gear", ObjectQuality::DEMO); //static VGlobalCreator<GearExample> gearCreator("Gear", 0); class DynamicGear : public GearExample { public: TypedSlot<VTime> myTime; DynamicGear (const string&name, int p, const RefPtr<VCreationPreferences>&VP) : GearExample(name, p, VP) , myTime(this, "time", VTime(0.0) ) { } void render(VGLRenderContext&Context) const { VTime t; myTime << Context >> t; printf("time t[%lg] \n", t() ); GLfloat red[4] = {0.1, 0.1, 0.1, 1.0 }; red[0] = 1-t(); red[2] = t(); GearRender(Context, red); } }; static Ref<VCreator<DynamicGear> > DynamicGearCreator("Demo/DynamicGear", ObjectQuality::DEMO); } VISH_DEFAULT_INIT