/* Function: modEuler * Description: Modified Euler Integrator using Implicit and Explicit * vi(t + h) = vi(t) + (ALPHA / h) * (gi(t) - xi(t)) + (h / mi) * Fext(t) * xi(t + h) = xi(t) + h * vi(t + h) * Input: None * Output: None */ void ModEuler(phyzx *phyzxObj, int mIndex, int deformMode) { point vertex, velocity, extVel, position, velDamp; point vDiff, velTotal, newPos, temp; matrix R, matTemp; memset( (void*)&temp, 0, sizeof(temp)); memset((void*)&extVel, 0, sizeof(point)); memset((void*)&velocity, 0, sizeof(point)); memset((void*)&position, 0, sizeof(point)); memset((void*)&vDiff, 0, sizeof(point)); memset((void*)&velTotal, 0, sizeof(point)); memset((void*)&newPos, 0, sizeof(point)); memset((void*)&phyzxObj->avgVel, 0, sizeof(point)); matInit(&R, 0, 0); matInit(&matTemp, 0, 0); if (deformMode == 3) quadDeformRot(&R, phyzxObj); for (unsigned int index = STARTFROM; index <= phyzxObj->model->numvertices; index++) { if (deformMode == 3) { // Compute Quadratic Deformation Goal Positions matMult(R, phyzxObj->q[index], &matTemp); // R(q) temp = matToPoint(matTemp); // Data type conversion pSUM(temp, phyzxObj->cmDeformed, phyzxObj->goal[index]); // g = R(q) + xcm } //end if else { // Compute Goal Positions matMult3331(phyzxObj->R, phyzxObj->relStableLoc[index], &temp); // R(xi0 - xcm0) pSUM(temp, phyzxObj->cmDeformed, phyzxObj->goal[index]); // g = R(xi0 - xcm0) + xcm } //end if vertex.x = phyzxObj->model->vertices[3*index]; vertex.y = phyzxObj->model->vertices[3*index + 1]; vertex.z = phyzxObj->model->vertices[3*index + 2];\ if (stickyFloor == 1) if (vertex.y <= -WALLDIST) continue; // Add user force if (mIndex == iMouseModel && lMouseVal == 2 && objectName != -1)// && index == objectName) { //point uForce; /*GLMnode *node; node = NBVStruct[objectName]; while (node->next != NULL) { pSUM(phyzxObj->extForce[node->index], userForce, phyzxObj->extForce[node->index]); node = node->next; } //end while*/ /*if (index != objectName) { point extPos = vMake(phyzxObj->model->vertices[3*objectName], phyzxObj->model->vertices[3*objectName+1], phyzxObj->model->vertices[3*objectName+2]); double dist = vecLeng(extPos, vertex); //if (dist > 0.04) //{ pMULTIPLY(userForce, (1.0/dist), uForce); pSUM(phyzxObj->extForce[index], uForce, phyzxObj->extForce[index]); //pDisp("user", userForce); //} //end if //else //{ //pSUM(phyzxObj->extForce[index], userForce, phyzxObj->extForce[index]); //} //end else } //end if else {*/ pSUM(phyzxObj->extForce[index], userForce, phyzxObj->extForce[index]); //} //end else } //end if // Explicit Euler Integrator for veloctiy -> vi(t + h) pDIFFERENCE(phyzxObj->goal[index], vertex, vDiff); // gi(t) - xi(t) pMULTIPLY(vDiff, (phyzxObj->alpha / phyzxObj->h), velocity); // vi(h) = (ALPHA / h) * (gi(t) - xi(t)) pMULTIPLY(phyzxObj->extForce[index], (phyzxObj->h / phyzxObj->mass[index]), extVel); // (h / mi) * Fext(t) // pMULTIPLY(phyzxObj->extForce[index], phyzxObj->h, extVel); // (h / mi) * Fext(t) pSUM(velocity, extVel, velTotal); // vi(h) = (ALPHA / h) * (gi(t) - xi(t)) + (h / mi) * Fext(t) pSUM(phyzxObj->velocity[index], velTotal, phyzxObj->velocity[index]); // vi(t + h) = vi(t) + vi(h) // Velocity Damping pMULTIPLY(phyzxObj->velocity[index], -phyzxObj->delta, velDamp); pSUM(phyzxObj->velocity[index], velDamp, phyzxObj->velocity[index]); // Implicity Euler Integrator for position pMULTIPLY(phyzxObj->velocity[index], phyzxObj->h, position); // xi(h) = h * vi(t + h) pSUM(vertex, position, newPos); // xi(t + h) = xi(t) + xi(h) // Store new position into data structure phyzxObj->model->vertices[3*index] = newPos.x; phyzxObj->model->vertices[3*index + 1] = newPos.y; phyzxObj->model->vertices[3*index + 2] = newPos.z; pSUM(phyzxObj->avgVel, phyzxObj->velocity[index], phyzxObj->avgVel); //if (objCollide) CheckForCollision(index, phyzxObj, mIndex); } //end for pMULTIPLY(phyzxObj->avgVel, 1.0 / phyzxObj->model->numvertices, phyzxObj->avgVel); delete[] R.data; delete[] matTemp.data; } //end ModEuler()
/* parse the program options */ int parsop(pScene sc,pMesh mesh) { FILE *in; pMaterial pm; double dd; float r,g,b,ca,cb,cc,na,nb,nc; int k,i,m,n,xs,ys,ret,ref,nbmat; char *ptr,ub,data[128],key[256],buf[256],pscol[32]; /* check if user-specified parameters */ iniopt(sc,mesh); strcpy(data,mesh->name); ptr = (char *)strstr(data,".mesh"); if ( ptr ) *ptr = '\0'; in = 0; if ( !strstr(data,".medit") ) { strcat(data,".medit"); in = fopen(data,"r"); } if ( !in ) { sprintf(data,"%s",DEFAULT_FILE); in = fopen(data,"r"); if ( !in ) { fprintf(stdout," Loading default options\n"); sc->par.nbmat = MAX_MATERIAL; matInit(sc); return(1); } } if ( !quiet ) fprintf(stdout," Reading %s\n",data); m = n = 0; while ( !feof(in) ) { fscanf(in,"%s",key); if ( feof(in) ) break; for (i=0; i<strlen(key); i++) key[i] = tolower(key[i]); if ( key[0] == '#' ) { fgets(key,255,in); } else if ( !strcmp(key,"backgroundcolor") ) { fscanf(in,"%f %f %f",&r,&g,&b); sc->par.back[0] = r; sc->par.back[1] = g; sc->par.back[2] = b; sc->par.back[3] = 1.0f; } else if ( !strcmp(key,"boundingbox") ) { fscanf(in,"%f %f %f %f %f %f",&ca,&cb,&cc,&na,&nb,&nc); mesh->xmin = ca; mesh->ymin = cb; mesh->zmin = cc; mesh->xmax = na; mesh->ymax = nb; mesh->zmax = nc; } else if ( !strcmp(key,"clipplane") ) { fscanf(in,"%f %f %f %f %f %f",&ca,&cb,&cc,&na,&nb,&nc); sc->par.clip[0] = ca - mesh->xtra; sc->par.clip[1] = cb - mesh->ytra; sc->par.clip[2] = cc - mesh->ztra; dd = sqrt(na*na + nb*nb + nc*nc); if ( dd > EPS ) { sc->par.clip[3] = na / dd; sc->par.clip[4] = nb / dd; sc->par.clip[5] = nc / dd; } } else if ( !strcmp(key,"linecolor") ) { fscanf(in,"%f %f %f",&r,&g,&b); sc->par.line[0] = r; sc->par.line[1] = g; sc->par.line[2] = b; sc->par.linc = 1; } else if ( !strcmp(key,"linewidth") ) { fscanf(in,"%f",&r); sc->par.linewidth = max(1.0,min(10.0,r)); sc->par.linc = 1; } else if ( !strcmp(key,"pointsize") ) { fscanf(in,"%f",&r); sc->par.pointsize = max(1.0,min(10.0,r)); sc->par.linc = 1; } else if ( !strcmp(key,"edgecolor") ) { fscanf(in,"%f %f %f",&r,&g,&b); sc->par.edge[0] = r; sc->par.edge[1] = g; sc->par.edge[2] = b; sc->par.linc = 1; } else if ( !strcmp(key,"sunposition") ) { fscanf(in,"%f %f %f",&r,&g,&b); sc->dmax = mesh->xmax - mesh->xmin; sc->dmax = max(sc->dmax,mesh->ymax - mesh->ymin); sc->dmax = max(sc->dmax,mesh->zmax - mesh->zmin); sc->dmax = fabs(sc->dmax); sc->par.sunpos[0] = 2.0*sc->dmax*r; sc->par.sunpos[1] = 2.0*sc->dmax*g; sc->par.sunpos[2] = 2.0*sc->dmax*b; sc->par.sunp = 1; } else if ( !strcmp(key,"windowsize") ) { fscanf(in,"%d %d",&xs,&ys); sc->par.xs = (short)xs; sc->par.ys = (short)ys; } else if ( !strcmp(key,"rendermode") ) { fscanf(in,"%s",buf); for (i=0; i<strlen(buf); i++) buf[i] = tolower(buf[i]); if ( strstr(buf,"hidden") ) sc->mode = HIDDEN; else if ( strstr(buf,"fill") ) sc->mode = FILL; else if ( strstr(buf,"colorshadingline") ) sc->mode = SHADED + S_MATERIAL; else if ( strstr(buf,"colorshading") ) sc->mode = S_FILL + S_COLOR + S_MATERIAL; else if ( strstr(buf,"shading") ) sc->mode = SHADED; } else if ( strstr(key,"palette") ) { sc->iso.palette = 1; if ( !strcmp(key,"palettet") ) sc->iso.palette = 1; else if ( !strcmp(key,"paletteb") ) sc->iso.palette = 2; else if ( !strcmp(key,"palettel") ) sc->iso.palette = 3; else if ( !strcmp(key,"paletter") ) sc->iso.palette = 4; for (k=0; k<MAXISO; k++) ret = fscanf(in,"%f",&sc->iso.val[k]); if ( sc->iso.val[MAXISO-1] < sc->iso.val[0] ) sc->iso.palette = 0; } else if ( !strcmp(key,"postscript") ) { fscanf(in,"%f %f %s %s",&sc->par.cm,&sc->par.dpi, buf,pscol); strncpy(sc->par.pscolor,pscol,10); sc->par.coeff = atof(buf); if ( sc->par.coeff < 0.0f ) sc->par.coeff = 0.0f; if ( sc->par.coeff > 1.0f ) sc->par.coeff = 1.0f; } else if ( !strcmp(key,"time") ) { ret = fscanf(in,"%f %f %f",&sc->par.maxtime,&sc->par.pertime,&sc->par.dt); if ( !EatSpace(in) ) { fscanf(in,"%c",&ub); sc->par.nbpart = max(atoi(&ub),1); } } else if ( !strcmp(key,"nbmaterial") ) { fscanf(in,"%d",&nbmat); sc->par.nbmat = max(2,nbmat); matInit(sc); } else if ( !strcmp(key,"material") ) { if ( sc->par.nbmat == -1 ) { sc->par.nbmat = MAX_MATERIAL; matInit(sc); } fgets(buf,255,in); if ( n > sc->par.nbmat ) continue; ret = sscanf(buf,"%s %d",buf,&ref); ptr = strstr(buf,"DEFAULT"); pm = ptr ? &sc->material[DEFAULT_MAT] : &sc->material[++n]; strcpy(pm->name,buf); if ( ret < 2 ) ref = 0; pm->ref = ref ? ref : n; fscanf(in,"%f %f %f %f",&pm->amb[0],&pm->amb[1],&pm->amb[2],&pm->amb[3]); fscanf(in,"%f %f %f %f",&pm->dif[0],&pm->dif[1],&pm->dif[2],&pm->dif[3]); fscanf(in,"%f %f %f %f",&pm->spe[0],&pm->spe[1],&pm->spe[2],&pm->spe[3]); fscanf(in,"%f %f %f %f",&pm->emi[0],&pm->emi[1],&pm->emi[2],&pm->emi[3]); fscanf(in,"%f",&pm->shininess); if ( pm->amb[3] == 0.0 ) pm->amb[3] = 1.0; if ( pm->dif[3] == 0.0 ) pm->dif[3] = 1.0; if ( pm->spe[3] == 0.0 ) pm->spe[3] = 1.0; if ( pm->emi[3] == 0.0 ) pm->emi[3] = 1.0; pm->shininess = min(fabs(pm->shininess),128.0f); pm->shininess = max(pm->shininess,3.0f); ++m; } /* stereo mode */ else if ( !strcmp(key,"eyesep") ) { fscanf(in,"%f",&sc->par.eyesep); } } fclose(in); if ( sc->par.nbmat < 0 ) { sc->par.nbmat = MAX_MATERIAL; matInit(sc); } else if ( m == n ) sc->par.nbmat++; if ( !sc->par.linc ) { sc->par.line[0] = 1.0 - sc->par.back[0]; sc->par.line[1] = 1.0 - sc->par.back[1]; sc->par.line[2] = 1.0 - sc->par.back[2]; } if ( ddebug ) fprintf(stdout," Materials %8d\n",sc->par.nbmat); return(1); }