void AeroCraftGUI:: camera (){
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    float fov = VIEW_ZOOM_DEFAULT/zoom;
    glFrustum( -ASPECT_RATIO, ASPECT_RATIO, -1, 1, 1*fov, VIEW_DEPTH*fov );
    Mat3d camMat;
    Vec3f camPos;
    convert(world->myCraft->pos, camPos );
    float camDist = 10.0;
    if(first_person){
        // third person camera attached to aero-craft
        camMat.setT( world->myCraft->rotMat );
        //glTranslatef ( -camPos.x, -camPos.y, -camPos.z );
    }else{
        // third person camera attached to aero-craft
        qCamera.toMatrix( camMat );
        camMat.T();
	}
	float glMat[16];
	Draw3D::toGLMatCam( { 0.0f, 0.0f, 0.0f}, camMat, glMat );
	glMultMatrixf( glMat );
    glTranslatef ( -camPos.x+camMat.cx*camDist, -camPos.y+camMat.cy*camDist, -camPos.z+camMat.cz*camDist );
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity();

}
void drawRigidBody( const RigidBody& rb, int npoints, Vec3d* points ){
    glColor3f(0.0f,0.0f,0.0f);

    glPushMatrix();
    float glMat[16];
    Mat3d rotT;
    rotT.setT(rb.rotMat);
    Draw3D::toGLMat( rb.pos, rotT, glMat );
    glMultMatrixf( glMat );
    if( points ) for(int i=0; i<npoints; i++) Draw3D::drawPointCross(points[i],0.3);
    glPopMatrix();

    glColor3f(1.0f,0.0f,1.0f); Draw3D::drawVecInPos( rb.L,     {0.0,0.0,0.0} );
    glColor3f(0.0f,0.0f,1.0f); Draw3D::drawVecInPos( rb.omega, {0.0,0.0,0.0} );

    if( points ){
        for(int i=0; i<npoints; i++){
            Vec3d p,v;
            //rb.rotMat.dot_to_T(points[i], p);
            //v.set_cross( p, rb.omega );        // omega is in global coordinates
            rb.velOfPoint( points[i], v, p );
            p.add(rb.pos);
            Draw3D::drawVecInPos  ( v, p );
            Draw3D::drawPointCross( p, 0.2 );
        }
    };
};
Exemple #3
0
void TetMesh::computeGradient(int element, const double * U, int numFields, double * grad) const
{
  // grad is 9 x numFields
  // grad is constant inside a tet
  Vec3d vtx[4];
  for(int i=0; i<4; i++)
    vtx[i] = *getVertex(element,i);

  // form M =
  // [b - a]
  // [c - a]
  // [d - a]

  Mat3d M(vtx[1] - vtx[0], vtx[2] - vtx[0], vtx[3] - vtx[0]);
  Mat3d MInv = inv(M);
  //printf("M=\n");
  //M.print();

  for(int field=0; field<numFields; field++)
  {
    // form rhs =
    // [U1 - U0]
    // [U2 - U0]
    // [U3 - U0]
    const double * u[4];
    for(int i=0; i<4; i++)
      u[i] = &U[3 * numVertices * field + 3 * getVertexIndex(element, i)];

    Vec3d rows[3];
    for(int i=0; i<3; i++)
      rows[i] = Vec3d(u[i+1]) - Vec3d(u[0]);

    Mat3d rhs(rows);
    //printf("rhs=\n");
    //rhs.print();

    Mat3d gradM = trans(MInv * rhs);
    gradM.convertToArray(&grad[9 * field]);

/*
    // test gradient
    if (field == 0)
    {
      printf("----\n");
      printf("0: pos: %.15f %.15f %.15f | uExact: %.15f %.15f %.15f\n", vtx[0][0], vtx[0][1], vtx[0][2], u[0][0], u[0][1], u[0][2]);
      for(int vertex=0; vertex<3; vertex++)
      {
        Vec3d u1 = Vec3d(u[vertex+1]);
        printf("%d: ", vertex+1);
        printf("pos: %.15f %.15f %.15f | uExact: %.15f %.15f %.15f | ", vtx[vertex+1][0], vtx[vertex+1][1], vtx[vertex+1][2], u1[0], u1[1], u1[2]);
        Vec3d u1approx = Vec3d(u[0]) + gradM * (vtx[vertex+1] - vtx[0]);
        printf("uApprox: %.15f %.15f %.15f\n", u1approx[0], u1approx[1], u1approx[2]);
      }
      printf("----\n");
    }
*/
  }
}
Exemple #4
0
		bool Spatial::rotateToHeading(Vec2d pos)
		{
			Vec2d toTarget = Vec2d(pos-mPos);
			toTarget.normalize();

			double angle = acos(mHeading.dot(pos));

			if (angle < 0.000001)
				return true;

			if (angle > mMaxTurnRate)
				angle = mMaxTurnRate;

			Mat3d rotationMat;
			rotationMat.rotate(angle*mHeading.sign(toTarget));
			rotationMat.transformVec2d(mHeading);
			rotationMat.transformVec2d(mVelocity);

			mSide = mHeading.perp();

			return false;
		}
void MolecularEditorApp::draw(){
    glClearColor( 0.5f, 0.5f, 0.5f, 0.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	//glDisable( GL_DEPTH_TEST );

    //converged = true;
    //delay = 100; world.optimizer->dt_max = 0.00001; world.optimizer->dt_max = 0.00001; perFrame=1;
    //delay = 1000; perFrame=1;
    //perFrame=1;  // world.optimizer->dt_max = 0.01;
    //world.optimizer->dt_max = 0.01;
    //world.nonCovalent  = false;
	if( !converged ){
        long tick1 = getCPUticks();
        int iter;
        for(iter=0; iter<perFrame; iter++){
            world.rigidOptStep( );
            printf(" opt step %i fmax %g \n", world.optimizer->stepsDone, world.fmax );
            if( world.fmax < fmaxConverg ){
                converged = true;
                printf(" converged after %i step \n", world.optimizer->stepsDone );
                if(fout_xyz){ fclose(fout_xyz); fout_xyz = NULL; }
                fout_xyz = fopen("relaxed.xyz", "w");
                char str[256];
                sprintf(str,"# fmax = %g", world.fmax );
                world.exportAtomsXYZ( fout_xyz, str );
                fclose(fout_xyz); fout_xyz = NULL;
                break;
            }
            if( (getCPUticks()-tick1)>4e+8 ) break;
        }
        double ticks = (getCPUticks() - tick1)/((double)perFrame);
        printf("======= %i %5.2f Mticks/iter %5.2f tick/atom %5.2f ticks/interaction \n", iter, ticks*1.0e-6, ticks/world.nAtomTot, ticks/world.nInteractions );

        world.saveInstances( "instances_lastStep.ini" );
        if(fout_xyz){
            char str[256];
            sprintf(str,"# fmax = %g", world.fmax );
            world.exportAtomsXYZ( fout_xyz, str );
        }
    }
    //exit(0);

    //world.nonBondingFroces_buf(); return;

	glMatrixMode(GL_MODELVIEW);
	//glMatrixMode(GL_PROJECTION);
	glEnable(GL_LIGHTING);
    for (int i=0; i<world.nmols; i++){
        if( world.instances[i]->viewlist > 0 ){
            Mat3d rotmat;
            float glMat[16];
            //rot[i].toMatrix_unitary2( rotmat );
            //rot[i].toMatrix_unitary( rotmat );
            //printf( "%i   (%3.3f,%3.3f,%3.3f) (%3.3f,%3.3f,%3.3f,%3.3f)\n", i,  world.pos[i].x,world.pos[i].y,world.pos[i].z,   world.rot[i].x,world.rot[i].y,world.rot[i].z,world.rot[i].w  );
            world.rot[i].toMatrix( rotmat );
            glColor3f(0.0f,0.0f,0.0f); Draw3D::drawPointCross(world.pos[i],1.0);
            Draw3D::toGLMat( world.pos[i], rotmat, glMat ); // somehow not working
            //Draw3D::toGLMat( {0.0,0.0,0.0}, rotmat, glMat );
            glPushMatrix();
            glMultMatrixf( glMat );
            //glTranslatef( world.pos[i].x,world.pos[i].y,world.pos[i].z );
            //glMultTransposeMatrixf( glMat );
            //glLoadMatrixf( glMat );
            glCallList   ( world.instances[i]->viewlist );
            glPopMatrix();
        }
    };

    //printf(" nLinkers %i &linkers %i \n" , world.nLinkers,  world.linkers );
    glDisable(GL_LIGHTING);
    glColor3f(0.0f,1.0f,0.0f);
    if( world.linkers ){
        for (int il=0; il<world.nLinkers; il++){
            Mat3d T;
            Vec3d gpi,gpj;
            MolecularLink& li =  world.linkers[il];
            int i = li.i;
            world.rot[i].toMatrix( T);
            T.dot_to( li.posi, gpi );
            gpi.add( world.pos[i] );

            int j = li.j;
            world.rot[j].toMatrix(T);
            T.dot_to( li.posj, gpj );
            gpj.add( world.pos[j] );

            Draw3D::drawLine(  gpi, gpj );
            Draw3D::drawPointCross(gpi,0.5);
            Draw3D::drawPointCross(gpj,0.5);

            //printf( "%i (%i,%i)  (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, i,j,   li.posi.x, li.posi.y, li.posi.z, li.posj.x, li.posj.y, li.posj.z );
            //printf( "%i          (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, gpi.x, gpi.y, gpi.z,   gpj.x,gpj.y,gpj.z);
        }
    }

    if( world.bonds ){
        for (int il=0; il<world.nBonds; il++){
            Mat3d T;
            Vec3d lpi,lpj,gpi,gpj;
            MolecularBond& bi =  world.bonds[il];
            int i = bi.imol;
            world.rot[i].toMatrix( T);
            lpi = world.instances[i]->xyzs[bi.iatom];
            T.dot_to( lpi, gpi );
            gpi.add( world.pos[i] );

            int j = bi.jmol;
            world.rot[j].toMatrix(T);
            lpj = world.instances[j]->xyzs[bi.jatom];
            T.dot_to( lpj, gpj );
            gpj.add( world.pos[j] );

            Draw3D::drawLine(  gpi, gpj );

            //printf( "%i (%i,%i)  (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, i,j,   li.posi.x, li.posi.y, li.posi.z, li.posj.x, li.posj.y, li.posj.z );
            //printf( "%i          (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, gpi.x, gpi.y, gpi.z,   gpj.x,gpj.y,gpj.z);
        }
    }

    //exit(0);

};
void PolarDecompositionGradient::Compute(const double * M, const double * Q, const double * S, const double * MDot, double * omega, double * QDot, double * SDot, const double * MDotDot, double * omegaDot, double * QDotDot)
{
  // compute omega = G^{-1} (2 * skew(Q^T * MDot)), where G = (tr(S)I - S) * Q^T
  // (see Barbic and Zhao, SIGGRAPH 2011)

  // first, construct G, and invert it

  // tempMatrix = tr(S)I - S
  double tempMatrix[9];
  for(int i=0; i<9; i++)
    tempMatrix[i] = -S[i];
  double trace = S[0] + S[4] + S[8];
  tempMatrix[0] += trace;
  tempMatrix[4] += trace;
  tempMatrix[8] += trace;

  double G[9]; // G = (tr(S)I - S) * Q^T
  MATRIX_MULTIPLY3X3ABT(tempMatrix, Q, G);
  Mat3d GM(G);
  Mat3d GInvM = inv(GM);
  double GInv[9];
  GInvM.convertToArray(GInv);

  // omega = GInv * (2 * skew(R^T * Mdot))
  MATRIX_MULTIPLY3X3ATB(Q, MDot, tempMatrix);
  double rhs[3];
  SKEW_PART(tempMatrix, rhs);
  VECTOR_SCALE3(rhs, 2.0);
  MATRIX_VECTOR_MULTIPLY3X3(GInv, rhs, omega);

  // compute QDot = tilde(omega) * Q
  double omegaTilde[9];
  SKEW_MATRIX(omega, omegaTilde);
  //double QDot[9];
  MATRIX_MULTIPLY3X3(omegaTilde, Q, QDot);

  // compute SDot = Q^T * (MDot - QDot * S)
  // tempMatrix = MDot - QDot * S
  MATRIX_MULTIPLY3X3(QDot, S, tempMatrix);
  for(int i=0; i<9; i++)
    tempMatrix[i] = MDot[i] - tempMatrix[i];
  // SDot = Q^T * tempMatrix
  MATRIX_MULTIPLY3X3ATB(Q, tempMatrix, SDot); 

  if ((MDotDot != NULL) && (omegaDot != NULL))
  {
    // compute omegaDot = GInv * ( 2 skew(Q^T (ADotDot - omegaTilde * ADot)) - (tr(SDot) I - SDot) * Q^T * omega )
    // (see Barbic and Zhao, SIGGRAPH 2011)
    
    // tempMatrix = MDotDot - omegaTilde * MDot
    MATRIX_MULTIPLY3X3(omegaTilde, MDot, tempMatrix);
    for(int i=0; i<9; i++)
      tempMatrix[i] = MDotDot[i] - tempMatrix[i];

    double tempMatrix2[9];
    // tempVector = 2 * skew(Q^T * tempMatrix)
    MATRIX_MULTIPLY3X3ATB(Q, tempMatrix, tempMatrix2);

    double tempVector[3];
    SKEW_PART(tempMatrix2, tempVector);
    VECTOR_SCALE3(tempVector, 2.0);

    // tempMatrix = tr(SDot)I - SDot
    for(int i=0; i<9; i++)
      tempMatrix[i] = -SDot[i];
    double trace = SDot[0] + SDot[4] + SDot[8];
    tempMatrix[0] += trace;
    tempMatrix[4] += trace;
    tempMatrix[8] += trace;

    // tempVector2 = (tempMatrix * Q^T) * omega
    double tempVector2[3];
    MATRIX_MULTIPLY3X3ABT(tempMatrix, Q, tempMatrix2);
    MATRIX_VECTOR_MULTIPLY3X3(tempMatrix2, omega, tempVector2);

    // tempVector -= tempVector2
    VECTOR_SUBTRACTEQUAL3(tempVector, tempVector2);

    // tempVector2 = GInv * tempVector
    MATRIX_VECTOR_MULTIPLY3X3(GInv, tempVector, omegaDot);

    if (QDotDot != NULL)
    {
      double tempMatrix[9];
      SKEW_MATRIX(omegaDot, tempMatrix);
      MATRIX_MULTIPLY3X3(omegaTilde, omegaTilde, tempMatrix2);
      for(int i=0;i<9;i++)
	tempMatrix[i] += tempMatrix2[i];
      MATRIX_MULTIPLY3X3(tempMatrix, Q, QDotDot);
    }
  }
}
TestAppBlockBuilder::TestAppBlockBuilder( int& id, int WIDTH_, int HEIGHT_ ) : AppSDL2OGL_3D( id, WIDTH_, HEIGHT_ ) {

	float l0_pos  [] = {0.1f,0.2f,1.0f,0}; glLightfv    ( GL_LIGHT0, GL_POSITION, l0_pos  );
	float l0_amb  [] = {0.0f,0.0f,0.0f,0}; glLightfv    ( GL_LIGHT0, GL_AMBIENT,  l0_amb  );
	float l0_diff [] = {0.4f,0.5f,0.4f,0}; glLightfv    ( GL_LIGHT0, GL_DIFFUSE,  l0_diff );
	float l0_spec [] = {0.0f,0.0f,0.0f,0}; glLightfv    ( GL_LIGHT0, GL_SPECULAR, l0_spec );
	glEnable     ( GL_LIGHT0           );

    float l1_pos  [] = {+1.0f,1.0f,1.0f,0}; glLightfv    ( GL_LIGHT1, GL_POSITION, l1_pos  );
	float l1_amb  [] = {0.0f,0.0f,0.0f,0}; glLightfv    ( GL_LIGHT1, GL_AMBIENT,  l1_amb  );
	float l1_diff [] = {0.2f,0.0f,0.0f,0}; glLightfv    ( GL_LIGHT1, GL_DIFFUSE,  l1_diff );
	float l1_spec [] = {0.0f,0.0f,0.0f,0}; glLightfv    ( GL_LIGHT1, GL_SPECULAR, l1_spec );
	glEnable     ( GL_LIGHT1           );

    float l2_pos  [] = {-1.0f,0.0f,1.0f,0}; glLightfv   ( GL_LIGHT2, GL_POSITION, l2_pos  );
	float l2_amb  [] = {0.0f,0.0f,0.0f,0}; glLightfv    ( GL_LIGHT2, GL_AMBIENT,  l2_amb  );
	float l2_diff [] = {0.0f,0.0f,0.2f,0}; glLightfv  ( GL_LIGHT2, GL_DIFFUSE,  l2_diff );
	float l2_spec [] = {0.0f,0.0f,0.0f,0}; glLightfv    ( GL_LIGHT2, GL_SPECULAR, l2_spec );
	glEnable     ( GL_LIGHT2           );

    glEnable     ( GL_LIGHTING         );


    camPos.set( 0,0,-10 );

    Mat3d rotMat;    rotMat.set( {1.0d,0.0d,0.0d}, {0.0d,1.0d,0.0d}, {0.0d,0.0d,1.0d} );
    BlockWorld::setupBlockWorld( {-127.0d,-127.0d,-127.0d}, {1.0d,1.0d,1.0d}, rotMat           );

    cursorShape = glGenLists(1);
    glNewList( cursorShape , GL_COMPILE );
        glPushMatrix();
        glScalef( 0.5f, 0.5f, 0.5f );
        glColor3f(0.01f,0.01f,0.01f); Draw3D::drawLines    ( Solids::Cube_nedges, Solids::Cube_edges, Solids::Cube_verts );
        //Draw3D::drawAxis( 0.5f );
        glPopMatrix();
    glEndList();

/*
    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
    glDisable ( GL_LIGHTING ); Draw3D::drawAxis( 0.5f );
    glEndList();
    nShapes++;
*/

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        //glPushMatrix();
        //glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        //Draw3D::drawConeFan        ( 16, 0.5f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        Draw3D::drawCone        ( 4, M_PI/4.0f, 9*M_PI/4.0f, (float)sqrt(0.5f), 0.01f, {0.0f,0.0f,0.5f}, {0.0f,0.0f,0.0f}, false );
        glBegin( GL_QUADS );
        glNormal3f( 0.0f, 0.0f, 1.0f );
        glVertex3f(  0.5f,  0.5f, 0.5f);
        glVertex3f(  0.5f, -0.5f, 0.5f);
        glVertex3f( -0.5f, -0.5f, 0.5f);
        glVertex3f( -0.5f,  0.5f, 0.5f);
        glEnd();
        //Draw3D::drawCylinderStrip  ( 16, 0.5f, 0.01f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        //glPopMatrix();
    glEndList();
    nShapes++;


    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        //glPushMatrix();
        //glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        //Draw3D::drawConeFan        ( 16, 0.5f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        Draw3D::drawCone        ( 16, 0.0f, M_PI/2.0f, 0.5f, 0.1f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f}, false );
        //Draw3D::drawCylinderStrip  ( 16, 0.5f, 0.01f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        //glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        //glPushMatrix();
        //glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        //Draw3D::drawConeFan        ( 16, 0.5f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        Draw3D::drawCone        ( 5, 0.0f, 2*M_PI, 0.5f, 0.1f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f}, false );
        //Draw3D::drawCylinderStrip  ( 16, 0.5f, 0.01f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        //glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        glPushMatrix();
        //glScalef( 0.5f, 0.5f, 0.5f );
        glTranslatef( -0.5f, 0.5f, 0.0f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        //Draw3D::drawConeFan        ( 16, 0.5f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        Draw3D::drawCone        ( 3, 0.0f, M_PI/2, 1.0f, 1.0f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f}, false );
        //Draw3D::drawCylinderStrip  ( 16, 0.5f, 0.01f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        //glPushMatrix();
        //glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        Draw3D::drawCylinderStrip  ( 16, 0.5f, 0.5f, {0.0f,0.0f,-0.5f}, {0.0f,0.0f,0.5f} );
        //glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        glPushMatrix();
        glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        Draw3D::drawPolygons( Solids::Cube_nfaces,        Solids::Cube_ngons,        Solids::Cube_faces,        Solids::Cube_verts        );
        glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        glPushMatrix();
        glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        Draw3D::drawPolygons( Solids::Tetrahedron_nfaces, Solids::Tetrahedron_ngons, Solids::Tetrahedron_faces, Solids::Tetrahedron_verts );
        glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        glPushMatrix();
        glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        Draw3D::drawPolygons( Solids::Octahedron_nfaces,  Solids::Octahedron_ngons,  Solids::Octahedron_faces,  Solids::Octahedron_verts  );
        glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        glPushMatrix();
        glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        Draw3D::drawPolygons( Solids::RhombicDodecahedron_nfaces,        Solids::RhombicDodecahedron_ngons,        Solids::RhombicDodecahedron_faces,        Solids::RhombicDodecahedron_verts        );
        glPopMatrix();
    glEndList();
    nShapes++;

    shapes[nShapes] = glGenLists(1);
    glNewList( shapes[nShapes] , GL_COMPILE );
        glPushMatrix();
        glScalef( 0.5f, 0.5f, 0.5f );
        glEnable ( GL_LIGHTING );
        glColor3f( 0.9f, 0.9f, 0.9f );
        Draw3D::drawPolygons( Solids::Icosahedron_nfaces,        Solids::Icosahedron_ngons,        Solids::Icosahedron_faces,        Solids::Icosahedron_verts        );
        glPopMatrix();
    glEndList();
    nShapes++;

/*
    blocks[nBlocks].shape       = shapes[iShape];
    blocks[nBlocks].orientation = 0;
    blocks[nBlocks].ix          = 2;
    blocks[nBlocks].iy          = 3;
    blocks[nBlocks].iz          = 4;
    nBlocks++;
*/

};
Exemple #8
0
int SVD(Mat3d & F, Mat3d & U, Vec3d & Sigma, Mat3d & V, double singularValue_eps, int modifiedSVD)
{
  // The code handles the following special situations:

  //---------------------------------------------------------
  // 1. det(V) == -1
  //    - multiply the first column of V by -1
  //---------------------------------------------------------
  // 2. An entry of Sigma is near zero
  //---------------------------------------------------------
  // (if modifiedSVD == 1) :
  // 3. negative determinant (Tet is inverted in solid mechanics).
  //    - check if det(U) == -1
  //    - If yes, then negate the minimal element of Sigma
  //      and the corresponding column of U
  //---------------------------------------------------------

  // form F^T F and do eigendecomposition
  Mat3d normalEq = trans(F) * F;
  Vec3d eigenValues;
  Vec3d eigenVectors[3];

  eigen_sym(normalEq, eigenValues, eigenVectors);

  V.set(eigenVectors[0][0], eigenVectors[1][0], eigenVectors[2][0],
    eigenVectors[0][1], eigenVectors[1][1], eigenVectors[2][1],
    eigenVectors[0][2], eigenVectors[1][2], eigenVectors[2][2]);
  /*
    printf("--- original V ---\n");
    V.print();
    printf("--- eigenValues ---\n");
    printf("%G %G %G\n", eigenValues[0], eigenValues[1], eigenValues[2]);
  */

  // Handle situation:
  // 1. det(V) == -1
  //    - multiply the first column of V by -1
  if (det(V) < 0.0)
  {
    // convert V into a rotation (multiply column 1 by -1)
    V[0][0] *= -1.0;
    V[1][0] *= -1.0;
    V[2][0] *= -1.0;
  }

  Sigma[0] = (eigenValues[0] > 0.0) ? sqrt(eigenValues[0]) : 0.0;
  Sigma[1] = (eigenValues[1] > 0.0) ? sqrt(eigenValues[1]) : 0.0;
  Sigma[2] = (eigenValues[2] > 0.0) ? sqrt(eigenValues[2]) : 0.0;

  //printf("--- Sigma ---\n");
  //printf("%G %G %G\n", Sigma[0][0], Sigma[1][1], Sigma[2][2]);

  // compute inverse of singular values
  // also check if singular values are close to zero
  Vec3d SigmaInverse;
  SigmaInverse[0] = (Sigma[0] > singularValue_eps) ? (1.0 / Sigma[0]) : 0.0;
  SigmaInverse[1] = (Sigma[1] > singularValue_eps) ? (1.0 / Sigma[1]) : 0.0;
  SigmaInverse[2] = (Sigma[2] > singularValue_eps) ? (1.0 / Sigma[2]) : 0.0;
  
  // compute U using the formula:
  // U = F * V * diag(SigmaInverse)
  U = F * V;
  U.multiplyDiagRight(SigmaInverse);

  // In theory, U is now orthonormal, U^T U = U U^T = I .. it may be a rotation or a reflection, depending on F.
  // But in practice, if singular values are small or zero, it may not be orthonormal, so we need to fix it.
  // Handle situation:
  // 2. An entry of Sigma is near zero
  // ---------------------------------------------------------

  /*
    printf("--- SigmaInverse ---\n");
    SigmaInverse.print();
    printf(" --- U ---\n");
    U.print();
  */
  
  if ((Sigma[0] < singularValue_eps) && (Sigma[1] < singularValue_eps) && (Sigma[2] < singularValue_eps))
  {
    // extreme case, all singular values are small, material has collapsed almost to a point
    // see [Irving 04], p. 4
    U.set(1.0, 0.0, 0.0,
          0.0, 1.0, 0.0,
          0.0, 0.0, 1.0);
  }
  else 
  {
    // handle the case where two singular values are small, but the third one is not
    // handle it by computing two (arbitrary) vectors orthogonal to the eigenvector for the large singular value
    int done = 0;
    for(int dim=0; dim<3; dim++)
    {
      int dimA = dim;
      int dimB = (dim + 1) % 3;
      int dimC = (dim + 2) % 3;
      if ((Sigma[dimB] < singularValue_eps) && (Sigma[dimC] < singularValue_eps))
      {
        // only the column dimA can be trusted, columns dimB and dimC correspond to tiny singular values
        Vec3d tmpVec1(U[0][dimA], U[1][dimA], U[2][dimA]); // column dimA
        Vec3d tmpVec2;
        tmpVec2 = tmpVec1.findOrthonormalVector();
        Vec3d tmpVec3 = norm(cross(tmpVec1, tmpVec2));
        U[0][dimB] = tmpVec2[0];
        U[1][dimB] = tmpVec2[1];
        U[2][dimB] = tmpVec2[2];
        U[0][dimC] = tmpVec3[0];
        U[1][dimC] = tmpVec3[1];
        U[2][dimC] = tmpVec3[2];
        if (det(U) < 0.0)
        {
          U[0][dimB] *= -1.0;
          U[1][dimB] *= -1.0;
          U[2][dimB] *= -1.0;
        }
        done = 1;
        break; // out of for
      }
    }

    // handle the case where one singular value is small, but the other two are not
    // handle it by computing the cross product of the two eigenvectors for the two large singular values
    if (!done) 
    {
      for(int dim=0; dim<3; dim++)
      {
        int dimA = dim;
        int dimB = (dim + 1) % 3;
        int dimC = (dim + 2) % 3;

        if (Sigma[dimA] < singularValue_eps)
        {
          // columns dimB and dimC are both good, but column dimA corresponds to a tiny singular value
          Vec3d tmpVec1(U[0][dimB], U[1][dimB], U[2][dimB]); // column dimB
          Vec3d tmpVec2(U[0][dimC], U[1][dimC], U[2][dimC]); // column dimC
          Vec3d tmpVec3 = norm(cross(tmpVec1, tmpVec2));
          U[0][dimA] = tmpVec3[0];
          U[1][dimA] = tmpVec3[1];
          U[2][dimA] = tmpVec3[2];
          if (det(U) < 0.0)
          {
            U[0][dimA] *= -1.0;
            U[1][dimA] *= -1.0;
            U[2][dimA] *= -1.0;
          }
          done = 1;
          break; // out of for
        }
      }
    }

    if ((!done) && (modifiedSVD == 1))
    {
      // Handle situation:
      // 3. negative determinant (Tet is inverted in solid mechanics)
      //    - check if det(U) == -1
      //    - If yes, then negate the minimal element of Sigma
      //      and the corresponding column of U

      double detU = det(U);
      if (detU < 0.0)
      {
        // negative determinant
        // find the smallest singular value (they are all non-negative)
        int smallestSingularValueIndex = 0;
        for(int dim=1; dim<3; dim++)
          if (Sigma[dim] < Sigma[smallestSingularValueIndex])
            smallestSingularValueIndex = dim;

        // negate the smallest singular value
        Sigma[smallestSingularValueIndex] *= -1.0;
        U[0][smallestSingularValueIndex] *= -1.0;
        U[1][smallestSingularValueIndex] *= -1.0;
        U[2][smallestSingularValueIndex] *= -1.0;
      }
    }
  }

  /*
    printf("U = \n");
    U.print();
    printf("Sigma = \n");
    Sigma.print();
    printf("V = \n");
    V.print();
  */

  return 0;
}
int ReducedStVKCubatureForceModel::ModifiedSVD(Mat3d & F, Mat3d & U, Vec3d & Fhat, Mat3d & V) const
{
    // The code handles the following necessary special situations (see the code below) :

    //---------------------------------------------------------
    // 1. det(V) == -1
    //    - simply multiply a column of V by -1
    //---------------------------------------------------------
    // 2. An entry of Fhat is near zero
    //---------------------------------------------------------
    // 3. Tet is inverted.
    //    - check if det(U) == -1
    //    - If yes, then negate the minimal element of Fhat
    //      and the corresponding column of U
    //---------------------------------------------------------

    double modifiedSVD_singularValue_eps = 1e-8;

    // form F^T F and do eigendecomposition
    Mat3d normalEq = trans(F) * F;
    Vec3d eigenValues;
    Vec3d eigenVectors[3];

    // note that normalEq is changed after calling eigen_sym
    eigen_sym(normalEq, eigenValues, eigenVectors);

    V.set(eigenVectors[0][0], eigenVectors[1][0], eigenVectors[2][0],
          eigenVectors[0][1], eigenVectors[1][1], eigenVectors[2][1],
          eigenVectors[0][2], eigenVectors[1][2], eigenVectors[2][2]);
    /*
      printf("--- original V ---\n");
      V.print();
      printf("--- eigenValues ---\n");
      printf("%G %G %G\n", eigenValues[0], eigenValues[1], eigenValues[2]);
    */

    // Handle situation:
    // 1. det(V) == -1
    //    - simply multiply a column of V by -1
    if (det(V) < 0.0)
    {
        // convert V into a rotation (multiply column 1 by -1)
        V[0][0] *= -1.0;
        V[1][0] *= -1.0;
        V[2][0] *= -1.0;
    }

    Fhat[0] = (eigenValues[0] > 0.0) ? sqrt(eigenValues[0]) : 0.0;
    Fhat[1] = (eigenValues[1] > 0.0) ? sqrt(eigenValues[1]) : 0.0;
    Fhat[2] = (eigenValues[2] > 0.0) ? sqrt(eigenValues[2]) : 0.0;

    //printf("--- Fhat ---\n");
    //printf("%G %G %G\n", Fhat[0][0], Fhat[1][1], Fhat[2][2]);

    // compute inverse of singular values
    // also check if singular values are close to zero
    Vec3d FhatInverse;
    FhatInverse[0] = (Fhat[0] > modifiedSVD_singularValue_eps) ? (1.0 / Fhat[0]) : 0.0;
    FhatInverse[1] = (Fhat[1] > modifiedSVD_singularValue_eps) ? (1.0 / Fhat[1]) : 0.0;
    FhatInverse[2] = (Fhat[2] > modifiedSVD_singularValue_eps) ? (1.0 / Fhat[2]) : 0.0;

    // compute U using the formula:
    // U = F * V * diag(FhatInverse)
    U = F * V;
    U.multiplyDiagRight(FhatInverse);

    // In theory, U is now orthonormal, U^T U = U U^T = I .. it may be a rotation or a reflection, depending on F.
    // But in practice, if singular values are small or zero, it may not be orthonormal, so we need to fix it.
    // Handle situation:
    // 2. An entry of Fhat is near zero
    // ---------------------------------------------------------

    /*
      printf("--- FhatInverse ---\n");
      FhatInverse.print();
      printf(" --- U ---\n");
      U.print();
    */

    if ((Fhat[0] < modifiedSVD_singularValue_eps) && (Fhat[1] < modifiedSVD_singularValue_eps) && (Fhat[2] < modifiedSVD_singularValue_eps))
    {
        // extreme case, material has collapsed almost to a point
        // see [Irving 04], p. 4
        U.set(1.0, 0.0, 0.0,
              0.0, 1.0, 0.0,
              0.0, 0.0, 1.0);
    }
    else
    {
        int done = 0;
        for(int dim=0; dim<3; dim++)
        {
            int dimA = dim;
            int dimB = (dim + 1) % 3;
            int dimC = (dim + 2) % 3;
            if ((Fhat[dimB] < modifiedSVD_singularValue_eps) && (Fhat[dimC] < modifiedSVD_singularValue_eps))
            {
                // only the column dimA can be trusted, columns dimB and dimC correspond to tiny singular values
                Vec3d tmpVec1(U[0][dimA], U[1][dimA], U[2][dimA]); // column dimA
                Vec3d tmpVec2;
                FindOrthonormalVector(tmpVec1, tmpVec2);
                Vec3d tmpVec3 = norm(cross(tmpVec1, tmpVec2));
                U[0][dimB] = tmpVec2[0];
                U[1][dimB] = tmpVec2[1];
                U[2][dimB] = tmpVec2[2];
                U[0][dimC] = tmpVec3[0];
                U[1][dimC] = tmpVec3[1];
                U[2][dimC] = tmpVec3[2];
                if (det(U) < 0.0)
                {
                    U[0][dimB] *= -1.0;
                    U[1][dimB] *= -1.0;
                    U[2][dimB] *= -1.0;
                }
                done = 1;
                break; // out of for
            }
        }

        if (!done)
        {
            for(int dim=0; dim<3; dim++)
            {
                int dimA = dim;
                int dimB = (dim + 1) % 3;
                int dimC = (dim + 2) % 3;

                if (Fhat[dimA] < modifiedSVD_singularValue_eps)
                {
                    // columns dimB and dimC are both good, but column dimA corresponds to a tiny singular value
                    Vec3d tmpVec1(U[0][dimB], U[1][dimB], U[2][dimB]); // column dimB
                    Vec3d tmpVec2(U[0][dimC], U[1][dimC], U[2][dimC]); // column dimC
                    Vec3d tmpVec3 = norm(cross(tmpVec1, tmpVec2));
                    U[0][dimA] = tmpVec3[0];
                    U[1][dimA] = tmpVec3[1];
                    U[2][dimA] = tmpVec3[2];
                    if (det(U) < 0.0)
                    {
                        U[0][dimA] *= -1.0;
                        U[1][dimA] *= -1.0;
                        U[2][dimA] *= -1.0;
                    }
                    done = 1;
                    break; // out of for
                }
            }
        }

        if (!done)
        {
            // Handle situation:
            // 3. Tet is inverted.
            //    - check if det(U) == -1
            //    - If yes, then negate the minimal element of Fhat
            //      and the corresponding column of U

            double detU = det(U);
            if (detU < 0.0)
            {
                // tet is inverted
                // find smallest singular value (they are all non-negative)
                int smallestSingularValueIndex = 0;
                for(int dim=1; dim<3; dim++)
                    if (Fhat[dim] < Fhat[smallestSingularValueIndex])
                        smallestSingularValueIndex = dim;

                // negate smallest singular value
                Fhat[smallestSingularValueIndex] *= -1.0;
                U[0][smallestSingularValueIndex] *= -1.0;
                U[1][smallestSingularValueIndex] *= -1.0;
                U[2][smallestSingularValueIndex] *= -1.0;
            }
        }
    }

    /*
      printf("U = \n");
      U.print();
      printf("Fhat = \n");
      Fhat.print();
      printf("V = \n");
      V.print();
    */

    return 0;
}
Tanks_single::Tanks_single( int& id, int WIDTH_, int HEIGHT_ ) : AppSDL2OGL_3D( id, WIDTH_, HEIGHT_ ) {

    world.init_world();
    printf( "DEBUG_SHIT : %i \n", world.debug_shit );

    // ---- terrain

    //new Terrain25D();
    world.terrain = prepareTerrain();

    // ---- Objects

    int sphereShape = glGenLists(1);
    glNewList( sphereShape , GL_COMPILE );
        //glPushMatrix();

        //glDisable ( GL_LIGHTING );
        //Draw3D::drawAxis ( 3.0f );
        //glColor3f( 1.0f, 0.0f, 1.0f ); Draw3D::drawLines   ( Solids::Icosahedron_nedges, Solids::Icosahedron_edges, Solids::Icosahedron_verts                             );

        //glEnable( GL_LIGHTING );
        //glColor3f( 0.8f, 0.8f, 0.8f ); Draw3D::drawPolygons( Solids::Icosahedron_nfaces, Solids::Icosahedron_ngons, Solids::Icosahedron_faces,  Solids::Icosahedron_verts );

        glEnable( GL_LIGHTING ); glColor3f( 0.8f, 0.8f, 0.8f );   Draw3D::drawSphere_oct( 6, 1.0, {0.0,0.0,0.0} );
        //glPopMatrix();
    glEndList();

    int nobjects=10;
    double xrange = 10.0;
    for( int i=0; i<nobjects; i++){
        Object3D * o = new Object3D();
        //o->bounds.orientation.set({});
        //o->bounds.span.set(o->bounds.orientation.a.normalize(),o->bounds.orientation.a.normalize(),o->bounds.orientation.a.normalize());
        o->bounds.orientation.fromRand( {randf(0,1),randf(0,1),randf(0,1)} );
        o->bounds.span.set( randf(0.2,2.0), randf(0.2,2.0), randf(0.2,2.0) );
        //o->bounds.span.set( 1, 2.0, 0.5 );
        Mat3d m; m.set_mmul_NT( o->bounds.orientation, o->bounds.orientation );
        /*
        printf( " === %i \n", i );
        printf( " %f %f %f \n", m.ax, m.ay, m.az );
        printf( " %f %f %f \n", m.bx, m.by, m.bz );
        printf( " %f %f %f \n", m.cx, m.cy, m.cz );
        */
        //o->bounds.pos.set( randf(-xrange,xrange),randf(-xrange,xrange),randf(-xrange,xrange) );
        Vec2d p,dv; p.set( randf(-xrange,xrange),randf(-xrange,xrange) );
        double v = world.terrain->eval( p, dv );
        o->bounds.pos.set( p.x, v, p.y );

        //o->bounds.pos.set( {0.0,0.0,0.0} );
        o->shape= sphereShape;
        o->id = i;
        world.objects.push_back(o);

    }

    //camPos.set();


    warrior1 = world.makeWarrior( {0.0d,0.0d,0.0d}, {0.0d,0.0d,1.0d}, {0.0d,1.0d,0.0d}, 0 );

    warrior1->pos.set( 0.0, 0.0, -15.0 );

    zoom = 5.0;
    first_person = true;
    perspective  = true;

}