예제 #1
0
void NoiseVolumeRenderer::drawImplementation(osg::State& state) const
{
	if(waterVolume() == 0) {
		return;
	}

	Point p;
	Point o = waterVolume()->origin();
	double dx = 1.0 / ((waterVolume()->sizeX() - 1) * waterVolume()->stepX());
	double dy = 1.0 / ((waterVolume()->sizeY() - 1) * waterVolume()->stepY());
	double dz = 1.0 / ((waterVolume()->sizeZ() - 1) * waterVolume()->stepZ());

	glBegin(GL_LINES);
		// x axis
		glColor4f(1.0, 0.0, 0.0, 1.0);
		p = waterVolume()->point(0, 0, 0);
		glVertex3d(p.x(), p.y(), p.z());
		p = waterVolume()->point(waterVolume()->sizeX()-1, 0, 0);
		glVertex3d(p.x(), p.y(), p.z());
		// y axis
		glColor4f(0.0, 1.0, 0.0, 1.0);
		p = waterVolume()->point(0, 0, 0);
		glVertex3d(p.x(), p.y(), p.z());
		p = waterVolume()->point(0, waterVolume()->sizeY()-1, 0);
		glVertex3d(p.x(), p.y(), p.z());
		// z axis
		glColor4f(0.0, 0.0, 1.0, 1.0);
		p = waterVolume()->point(0, 0, 0);
		glVertex3d(p.x(), p.y(), p.z());
		p = waterVolume()->point(0, 0, waterVolume()->sizeZ()-1);
		glVertex3d(p.x(), p.y(), p.z());
	glEnd();

	Locker lock(waterVolume());

	// showing velocities
/*	glBegin(GL_LINES);
	glColor4d(1.0, 1.0, 1.0, 1.0);
	for(unsigned i = 0; i < waterVolume()->sizeX(); i++) {
		for(unsigned j = 0; j < waterVolume()->sizeY(); j++) {
			for(unsigned k = 0; k < waterVolume()->sizeZ(); k++) {
				Vector v = waterVolume()->velocity(i, j, k);
				Point p1 = waterVolume()->point(i, j, k);
				Point p2 = p1 + v;
				glVertex3d(p1.x(), p1.y(), p1.z());
				glVertex3d(p2.x(), p2.y(), p2.z());
			}
		}
	}
	glEnd();*/

	double tr = 1.0 / threshold();
	// showing densities
	for(unsigned i = 1; i < waterVolume()->sizeX() - 1; i++) {
		for(unsigned j = 1; j < waterVolume()->sizeY() - 1; j++) {
			for(unsigned k = 1; k < waterVolume()->sizeZ() - 1; k++) {
				Vector n;
				double x, y, z, t, d;

				// cube vertices
				Point p1 = waterVolume()->point(  i,   j,   k);
				Point p2 = waterVolume()->point(i+1,   j, k+1);
				Point p3 = waterVolume()->point(i+1,   j,   k);
				Point p4 = waterVolume()->point(i+1, j+1, k+1);
				Point p5 = waterVolume()->point(i+1, j+1,   k);
				Point p6 = waterVolume()->point(  i, j+1, k+1);
				Point p7 = waterVolume()->point(  i, j+1,   k);
				Point p8 = waterVolume()->point(  i,   j, k+1);

				glBegin(GL_TRIANGLE_STRIP);

				// first face
				n = ((p3 - p1) ^ (p2 - p1)).normalise();
				glNormal3d(n.x(), n.y(), n.z());

				x = (p8.x() - o.x()) * dx;
				y = (p8.y() - o.y()) * dy;
				z = (p8.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i, j, k+1) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p8.x(), p8.y(), p8.z());

				x = (p1.x() - o.x()) * dx;
				y = (p1.y() - o.y()) * dy;
				z = (p1.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i, j, k) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p1.x(), p1.y(), p1.z());

				x = (p2.x() - o.x()) * dx;
				y = (p2.y() - o.y()) * dy;
				z = (p2.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i+1, j, k+1) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p2.x(), p2.y(), p2.z());

				x = (p3.x() - o.x()) * dx;
				y = (p3.y() - o.y()) * dy;
				z = (p3.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i+1, j, k) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p3.x(), p3.y(), p3.z());

				// second face
				n = ((p5 - p3) ^ (p4 - p3)).normalise();
				glNormal3d(n.x(), n.y(), n.z());

				x = (p4.x() - o.x()) * dx;
				y = (p4.y() - o.y()) * dy;
				z = (p4.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i+1, j+1, k+1) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p4.x(), p4.y(), p4.z());

				x = (p5.x() - o.x()) * dx;
				y = (p5.y() - o.y()) * dy;
				z = (p5.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i+1, j+1, k) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p5.x(), p5.y(), p5.z());

				// third face
				n = ((p7 - p5) ^ (p6 - p5)).normalise();
				glNormal3d(n.x(), n.y(), n.z());

				x = (p6.x() - o.x()) * dx;
				y = (p6.y() - o.y()) * dy;
				z = (p6.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i, j+1, k+1) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p6.x(), p6.y(), p6.z());

				x = (p7.x() - o.x()) * dx;
				y = (p7.y() - o.y()) * dy;
				z = (p7.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i, j+1, k) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p7.x(), p7.y(), p7.z());

				// fourth face
				n = ((p1 - p7) ^ (p8 - p7)).normalise();
				glNormal3d(n.x(), n.y(), n.z());

				x = (p8.x() - o.x()) * dx;
				y = (p8.y() - o.y()) * dy;
				z = (p8.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i, j, k+1) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p8.x(), p8.y(), p8.z());

				x = (p1.x() - o.x()) * dx;
				y = (p1.y() - o.y()) * dy;
				z = (p1.z() - o.z()) * dz;
				t = ImprovedNoise::noise(x, y, z) + 0.5;
				d = waterVolume()->density(i, j, k) * tr;
				glColor4d(t, t, t, d);
				glTexCoord3d(x, y, z);
				glVertex3d(p1.x(), p1.y(), p1.z());

				glEnd();
			}
		}
	}
}
void Law2_ScGeom_CapillaryPhys_Capillarity1::action()
{
    bool switched = (switchTriangulation == (imposePressure or totalVolumeConstant));
    switchTriangulation = (imposePressure or totalVolumeConstant);
    InteractionContainer::iterator ii = scene->interactions->begin();
    InteractionContainer::iterator iiEnd = scene->interactions->end();  
    if (imposePressure) {
      solver(capillaryPressure,switched);
    }
    else{
      if (((totalVolumeConstant || (!totalVolumeConstant && firstIteration==1)) && totalVolumeofWater!=-1) || (totalVolumeConstant && totalVolumeofWater==-1))
      { 
	if (!totalVolumeConstant) x=1;
	totalVolumeConstant=1;
	Real p0=capillaryPressure;
	Real slope;
	Real eps=0.0000000001;
	solver(p0,switched);
	Real V0=waterVolume();
	if (totalVolumeConstant && totalVolumeofWater==-1 && firstIteration==1){
	  totalVolumeofWater=V0;
	  firstIteration+=1;
	}
	Real p1=capillaryPressure+0.1;
	solver(p1,switched);
	Real V1=waterVolume();
	while (abs((totalVolumeofWater-V1)/totalVolumeofWater)>eps){
	  slope= (p1-p0)/(V1-V0);
	  p0=p1;
	  V0=V1;
	  p1=p1-slope*(V1-totalVolumeofWater);
	  if (p1<0) {
	    cout<< "The requested volume of water is quite big, the simulation will continue at constant suction.:"<< p0 <<endl;
  	    capillaryPressure=p0;
 	    imposePressure=1;
 	    break;
	  }
	  solver(p1,switched);
	  V1=waterVolume();
	  capillaryPressure=p1;
	}
	if (x==1){
	  totalVolumeConstant=0;
	  firstIteration+=1;
	}
      }
      else{
	if ((!totalVolumeConstant && firstIteration==1) && totalVolumeofWater==-1){
	  totalVolumeConstant=1;
	  solver(capillaryPressure,switched);
	  firstIteration+=1;
	  totalVolumeConstant=0;
	}
	else 
	{ 
	  solver(capillaryPressure,switched);
	}

      }
    }
    for (ii= scene->interactions->begin(); ii!=iiEnd ; ++ii) {
      CapillaryPhys1* phys = dynamic_cast<CapillaryPhys1*>((*ii)->phys.get());
        if ((*ii)->isReal() && phys-> computeBridge==true) {
            CapillaryPhys1* cundallContactPhysics=NULL;
            MindlinCapillaryPhys* mindlinContactPhysics=NULL;
            if (!hertzOn) cundallContactPhysics = static_cast<CapillaryPhys1*>((*ii)->phys.get());//use CapillaryPhys for linear model
            else mindlinContactPhysics = static_cast<MindlinCapillaryPhys*>((*ii)->phys.get());//use MindlinCapillaryPhys for hertz model

            if ((hertzOn && mindlinContactPhysics->meniscus) || (!hertzOn && cundallContactPhysics->meniscus)) {
                if (fusionDetection) {//version with effect of fusion
//BINARY VERSION : if fusionNumber!=0 then no capillary force
                    short int& fusionNumber = hertzOn?mindlinContactPhysics->fusionNumber:cundallContactPhysics->fusionNumber;
                    if (binaryFusion) {
                        if (fusionNumber!=0) {	//cerr << "fusion" << endl;
                            hertzOn?mindlinContactPhysics->fCap:cundallContactPhysics->fCap = Vector3r::Zero();
                            continue;
                        }
                    }
//LINEAR VERSION : capillary force is divided by (fusionNumber + 1) - NOTE : any decreasing function of fusionNumber can be considered in fact
                    else if (fusionNumber !=0) hertzOn?mindlinContactPhysics->fCap:cundallContactPhysics->fCap /= (fusionNumber+1.);
                }
                scene->forces.addForce((*ii)->getId1(), hertzOn?mindlinContactPhysics->fCap:cundallContactPhysics->fCap);
                scene->forces.addForce((*ii)->getId2(),-(hertzOn?mindlinContactPhysics->fCap:cundallContactPhysics->fCap));
            }
        }
    }

}