Beispiel #1
0
C3DModel CTriangulator<Real, OBB3<Real> >::Triangulate(const OBB3<Real> &pShape)
{

  C3DModel model;

  std::vector<Vector3<Real> > vVertices;
  std::vector<TriFace>         vFaces;

	Vector3<Real> vertices[8];
	pShape.computeVertices(vertices);
	for(int i=0;i<8;i++)
		vVertices.push_back(vertices[i]);
	
	//front faces
	int verts[3];
	verts[0]=0;
	verts[1]=1;
	verts[2]=5;
	TriFace face(verts);
	vFaces.push_back(face);	
	verts[0]=0;
	verts[1]=5;
	verts[2]=4;
	face=TriFace(verts);
	vFaces.push_back(face);
	//back faces
	verts[0]=3;
	verts[1]=6;
	verts[2]=7;
	face=TriFace(verts);
	vFaces.push_back(face);	
	verts[0]=3;
	verts[1]=2;
	verts[2]=6;
	face=TriFace(verts);
	vFaces.push_back(face);
	//bottom faces
	verts[0]=0;
	verts[1]=1;
	verts[2]=2;
	face=TriFace(verts);
	vFaces.push_back(face);	
	verts[0]=0;
	verts[1]=2;
	verts[2]=3;
	face=TriFace(verts);
	vFaces.push_back(face);
	//top faces
	verts[0]=4;
	verts[1]=5;
	verts[2]=6;
	face=TriFace(verts);
	vFaces.push_back(face);	
	verts[0]=4;
	verts[1]=6;
	verts[2]=7;
	face=TriFace(verts);
	vFaces.push_back(face);
	//left faces
	verts[0]=3;
	verts[1]=7;
	verts[2]=4;
	face=TriFace(verts);
	vFaces.push_back(face);	
	verts[0]=3;
	verts[1]=4;
	verts[2]=0;
	face=TriFace(verts);
	vFaces.push_back(face);
	//right faces
	verts[0]=1;
	verts[1]=2;
	verts[2]=6;
	face=TriFace(verts);
	vFaces.push_back(face);	
	verts[0]=1;
	verts[1]=6;
	verts[2]=5;
	face=TriFace(verts);
	vFaces.push_back(face);
	
  model.CreateFrom(vVertices,vFaces);

  return model;
}
Beispiel #2
0
 const Point& vertex_of_face(size_t v, size_t f) const
 { return vertex(face(f)(v)); }
Beispiel #3
0
void TET::drawFaces()
{
  for(int x = 0; x < 4; x++)
    face(x).draw();
}
Beispiel #4
0
const MGFace* MGShell::face(size_t i)const{
	const_pcellItr j=pcell_begin();
	std::advance(j,i);
	return face(j);
}
bool Foam::solidParticle::move(solidParticle::trackData& td)
{
    td.switchProcessor = false;
    td.keepParticle = true;

    const polyMesh& mesh = cloud().pMesh();
    const polyBoundaryMesh& pbMesh = mesh.boundaryMesh();

    scalar deltaT = mesh.time().deltaT().value();
    scalar tEnd = (1.0 - stepFraction())*deltaT;
    scalar dtMax = tEnd;

    while (td.keepParticle && !td.switchProcessor && tEnd > SMALL)
    {
        if (debug)
        {
            Info<< "Time = " << mesh.time().timeName()
                << " deltaT = " << deltaT
                << " tEnd = " << tEnd
                << " steptFraction() = " << stepFraction() << endl;
        }

        // set the lagrangian time-step
        scalar dt = min(dtMax, tEnd);

        // remember which cell the parcel is in
        // since this will change if a face is hit
        label celli = cell();

        dt *= trackToFace(position() + dt*U_, td);

        tEnd -= dt;
        stepFraction() = 1.0 - tEnd/deltaT;

        cellPointWeight cpw(mesh, position(), celli, face());
        scalar rhoc = td.rhoInterp().interpolate(cpw);
        vector Uc = td.UInterp().interpolate(cpw);
        scalar nuc = td.nuInterp().interpolate(cpw);

        scalar rhop = td.spc().rhop();
        scalar magUr = mag(Uc - U_);

        scalar ReFunc = 1.0;
        scalar Re = magUr*d_/nuc;

        if (Re > 0.01)
        {
            ReFunc += 0.15*pow(Re, 0.687);
        }

        scalar Dc = (24.0*nuc/d_)*ReFunc*(3.0/4.0)*(rhoc/(d_*rhop));

        U_ = (U_ + dt*(Dc*Uc + (1.0 - rhoc/rhop)*td.g()))/(1.0 + dt*Dc);

        if (onBoundary() && td.keepParticle)
        {
            if (isA<processorPolyPatch>(pbMesh[patch(face())]))
            {
                td.switchProcessor = true;
            }
        }
    }

    return td.keepParticle;
}
Beispiel #6
0
void
Surface_mesh::
split(Edge e, Vertex v)
{
    Halfedge h0 = halfedge(e, 0);
    Halfedge o0 = halfedge(e, 1);

    Vertex   v2 = to_vertex(o0);

    Halfedge e1 = new_edge(v, v2);
    Halfedge t1 = opposite_halfedge(e1);

    Face     f0 = face(h0);
    Face     f3 = face(o0);

    set_halfedge(v, h0);
    set_vertex(o0, v);

    if (!is_boundary(h0))
    {
        Halfedge h1 = next_halfedge(h0);
        Halfedge h2 = next_halfedge(h1);

        Vertex   v1 = to_vertex(h1);

        Halfedge e0 = new_edge(v, v1);
        Halfedge t0 = opposite_halfedge(e0);

        Face f1 = new_face();
        set_halfedge(f0, h0);
        set_halfedge(f1, h2);

        set_face(h1, f0);
        set_face(t0, f0);
        set_face(h0, f0);

        set_face(h2, f1);
        set_face(t1, f1);
        set_face(e0, f1);

        set_next_halfedge(h0, h1);
        set_next_halfedge(h1, t0);
        set_next_halfedge(t0, h0);

        set_next_halfedge(e0, h2);
        set_next_halfedge(h2, t1);
        set_next_halfedge(t1, e0);
    }
    else
    {
        set_next_halfedge(prev_halfedge(h0), t1);
        set_next_halfedge(t1, h0);
        // halfedge handle of _vh already is h0
    }


    if (!is_boundary(o0))
    {
        Halfedge o1 = next_halfedge(o0);
        Halfedge o2 = next_halfedge(o1);

        Vertex v3 = to_vertex(o1);

        Halfedge e2 = new_edge(v, v3);
        Halfedge t2 = opposite_halfedge(e2);

        Face f2 = new_face();
        set_halfedge(f2, o1);
        set_halfedge(f3, o0);

        set_face(o1, f2);
        set_face(t2, f2);
        set_face(e1, f2);

        set_face(o2, f3);
        set_face(o0, f3);
        set_face(e2, f3);

        set_next_halfedge(e1, o1);
        set_next_halfedge(o1, t2);
        set_next_halfedge(t2, e1);

        set_next_halfedge(o0, e2);
        set_next_halfedge(e2, o2);
        set_next_halfedge(o2, o0);
    }
    else
    {
        set_next_halfedge(e1, next_halfedge(o0));
        set_next_halfedge(o0, e1);
        set_halfedge(v, e1);
    }

    if (halfedge(v2) == h0)
        set_halfedge(v2, t1);
}
Beispiel #7
0
void Sighter::procSight(cv::Mat &frame, cv::Mat &lfeat, cv::Mat &rfeat) {


    cv::cvtColor(frame, drawMat, CV_BGRA2BGR);
    cv::flip(drawMat, drawMat, 1);

    cv::cvtColor(drawMat, grayMat, CV_BGR2GRAY);

    cv::Rect frect;

    cv::Mat& draw = drawMat;
    cv::Mat& gray = grayMat;

    //Detect face
    cv::vector<cv::Rect> faces;
    faceDetector.detectMultiScale(gray, faces, 1.1, 20, CV_HAAR_DO_CANNY_PRUNING|CV_HAAR_FIND_BIGGEST_OBJECT, cv::Size(gray.cols/4,gray.rows/4));

    if(faces.empty()) {
        return;
    }

    frect = faces[0];

    cv::Mat face = gray(frect);

    //Detect eye
    cv::vector<cv::Rect> leyes,reyes;

    cv::Size max_size = cv::Size(face.cols/2,face.rows/4);
    cv::Size min_size = cv::Size(face.cols/10, 10);

    cv::Mat lface = face(cv::Rect(0,face.rows/4,face.cols/2,face.rows/3));
    eyeDetector.detectMultiScale(lface, leyes, 1.1, 20, CV_HAAR_DO_CANNY_PRUNING, min_size, max_size);

    cv::Mat rface = face(cv::Rect(face.cols/2,face.rows/4,face.cols/2,face.rows/3));
    eyeDetector.detectMultiScale(rface, reyes, 1.1, 20, CV_HAAR_DO_CANNY_PRUNING, min_size, max_size);

    int szl = (int)leyes.size();
    int szr = (int)reyes.size();

    if(szl < 1 || szr < 1) {
        return;
    }


    //have min vertical difference
    int min_dy = INT_MAX;
    cv::Rect lerect, rerect;
    for(int i=0;i<szl;i++) {

        int cy = leyes[i].y + leyes[i].height/2;

        for(int j=0;j<szr;j++) {

            int cyr = reyes[j].y + reyes[j].height/2;

            int d = abs(cy-cyr);

            if( d < min_dy) {
                min_dy = d;
                lerect = leyes[i];
                rerect = reyes[j];
            }
        }
    }

    //transform to worldwide coordinate
    lerect.x += frect.x;
    lerect.y += frect.y + frect.height/4;

    rerect.x += frect.x + frect.width/2;
    rerect.y += frect.y + frect.height/4;


    //classifing eye's action
    cv::Mat legray = gray(lerect);
    cv::Mat regray = gray(rerect);

    cv::flip(regray, regray, 1);

    lfeat = legray;
    rfeat = regray;

    cv::Mat sample(50,50,CV_8UC1);

    cv::resize(legray, sample, sample.size());


    int ldir = -1;
    if(eyeActM)
        ldir = eyeActM->predict(sample);

    cv::resize(regray, sample, sample.size());

    int rdir = -1;
    if(eyeActM)
        rdir = eyeActM->predict(sample);


    SightState sstate = STARE_NONE;
    if( ldir == 0 && rdir == 0 ) {
        sstate = STARE_CENTER;
    }
    if( ldir == 2 && rdir == 1) {
        sstate = STARE_LEFT;

    }
    if( ldir == 1 && rdir == 2) {
        sstate = STARE_RIGHT;
    }

    {
#define ACT_STAT_TOTAL 10

        static SightState sstates[ACT_STAT_TOTAL] = {STARE_NONE};
        static int ssi = 0;
        static int ssleft = 0;
        static int ssright = 0;
        static int sscenter = 0;
        static int ssnone = ACT_STAT_TOTAL;

        switch(sstates[ssi]) {
            case STARE_NONE:
                ssnone--;
                break;
            case STARE_LEFT:
                ssleft--;
                break;
            case STARE_RIGHT:
                ssright--;
                break;
            case STARE_CENTER:
                sscenter--;
                break;
            default:
                break;
        }
        switch(sstate) {
            case STARE_NONE:
                ssnone++;
                if(ssnone >= ACT_STAT_TOTAL*0.6) {
                    sightState = STARE_NONE;
                }
                break;
            case STARE_LEFT:
                ssleft++;
                if(ssleft >= ACT_STAT_TOTAL*0.6) {
                    sightState = STARE_LEFT;
                }
                break;
            case STARE_RIGHT:
                ssright++;
                if(ssright >= ACT_STAT_TOTAL*0.6) {
                    sightState = STARE_RIGHT;
                }

                break;
            case STARE_CENTER:
                sscenter++;
                if(sscenter >= ACT_STAT_TOTAL*0.6) {
                    sightState = STARE_CENTER;
                }
                break;
            default:
                break;
        }

        sstates[ssi] = sstate;
        ssi = (ssi+1)%ACT_STAT_TOTAL;


    }


    //tracking the pupil
    pulLeft.procPupil(legray);
    pulRight.procPupil(regray);



    pulLeft.pulCenter += lerect.tl();
    pulRight.pulCenter += rerect.tl();



    //Drawing

    int r = MAX(pulLeft.pulRect.height, pulRight.pulRect.height)/3;

    static int ani_r = 100;
    static int ani_speed = 5;


    if(ani_r > 0) {


        cv::circle(draw, pulLeft.pulCenter, ani_r, CV_RGB(255,0,0),1.5);
        cv::circle(draw, pulRight.pulCenter, ani_r, CV_RGB(255,0,0),1.5);
        ani_r -= ani_speed;
        ani_speed += 5;

    }
    else if( r > 0 ) {



        cv::circle(draw, pulLeft.pulCenter, r, CV_RGB(255,0,0), CV_FILLED);
        cv::circle(draw, pulLeft.pulCenter, r*3, CV_RGB(255,0,0), 1);

        cv::circle(draw, pulRight.pulCenter, r, CV_RGB(255,0,0), CV_FILLED);
        cv::circle(draw, pulRight.pulCenter, r*3, CV_RGB(255,0,0), 1);


    }

    cv::rectangle(draw, frect, CV_RGB(255,255,0));
    cv::rectangle(draw, lerect, CV_RGB(0,255,0));
    cv::rectangle(draw, rerect, CV_RGB(0,255,0));
}
Beispiel #8
0
    forAll(patchTopologyFaces, patchTopologyFaceLabel)
    {
        label blockLabel = blockLabels[patchTopologyFaceLabel];

        faceList blockFaces
        (
            blocks[blockLabel].blockDef().blockShape().faces()
        );

        forAll(blockFaces, blockFaceLabel)
        {
            if
            (
                blockFaces[blockFaceLabel]
                == patchTopologyFaces[patchTopologyFaceLabel]
            )
            {
                const labelListList& blockPatchFaces =
                    blocks[blockLabel].boundaryPatches()[blockFaceLabel];

                forAll(blockPatchFaces, blockFaceLabel)
                {
                    // Lookup the face points
                    // and collapse duplicate point labels

                    quadFace[0] =
                        mergeList_
                        [
                            blockPatchFaces[blockFaceLabel][0]
                          + blockOffsets_[blockLabel]
                        ];

                    label nUnique = 1;

                    for
                    (
                        label facePointLabel = 1;
                        facePointLabel < 4;
                        facePointLabel++
                    )
                    {
                        quadFace[nUnique] =
                            mergeList_
                            [
                                blockPatchFaces[blockFaceLabel][facePointLabel]
                              + blockOffsets_[blockLabel]
                            ];

                        if (quadFace[nUnique] != quadFace[nUnique-1])
                        {
                            nUnique++;
                        }
                    }

                    if (quadFace[nUnique-1] == quadFace[0])
                    {
                        nUnique--;
                    }

                    if (nUnique == 4)
                    {
                        patchFaces[faceLabel++] = quadFace;
                    }
                    else if (nUnique == 3)
                    {
                        patchFaces[faceLabel++] = face
                        (
                            labelList::subList(quadFace, 3)
                        );
                    }
                    // else the face has collapsed to an edge or point
                }
            }
        }
Beispiel #9
0
void ConcavePolygonShapeSW::_setup(DVector<Vector3> p_faces) {

	int src_face_count=p_faces.size();
	ERR_FAIL_COND(src_face_count%3);
	src_face_count/=3;

	DVector<Vector3>::Read r = p_faces.read();
	const Vector3 * facesr= r.ptr();

#if 0
	Map<Vector3,int> point_map;
	List<Face> face_list;


	for(int i=0;i<src_face_count;i++) {

		Face3 faceaux;

		for(int j=0;j<3;j++) {

			faceaux.vertex[j]=facesr[i*3+j].snapped(_POINT_SNAP);
			//faceaux.vertex[j]=facesr[i*3+j];//facesr[i*3+j].snapped(_POINT_SNAP);
		}

		ERR_CONTINUE( faceaux.is_degenerate() );

		Face face;

		for(int j=0;j<3;j++) {


			Map<Vector3,int>::Element *E=point_map.find(faceaux.vertex[j]);
			if (E) {

				face.indices[j]=E->value();
			} else {

				face.indices[j]=point_map.size();
				point_map.insert(faceaux.vertex[j],point_map.size());

			}
		}

		face_list.push_back(face);
	}

	vertices.resize( point_map.size() );

	DVector<Vector3>::Write vw = vertices.write();
	Vector3 *verticesw=vw.ptr();

	AABB _aabb;

	for( Map<Vector3,int>::Element *E=point_map.front();E;E=E->next()) {

		if (E==point_map.front()) {
			_aabb.pos=E->key();
		} else {

			_aabb.expand_to(E->key());
		}
		verticesw[E->value()]=E->key();
	}

	point_map.clear(); // not needed anymore

	faces.resize(face_list.size());
	DVector<Face>::Write w = faces.write();
	Face *facesw=w.ptr();

	int fc=0;

	for( List<Face>::Element *E=face_list.front();E;E=E->next()) {

		facesw[fc++]=E->get();
	}

	face_list.clear();


	DVector<_VolumeSW_BVH_Element> bvh_array;
	bvh_array.resize( fc );

	DVector<_VolumeSW_BVH_Element>::Write bvhw = bvh_array.write();
	_VolumeSW_BVH_Element *bvh_arrayw=bvhw.ptr();


	for(int i=0;i<fc;i++) {

		AABB face_aabb;
		face_aabb.pos=verticesw[facesw[i].indices[0]];
		face_aabb.expand_to( verticesw[facesw[i].indices[1]] );
		face_aabb.expand_to( verticesw[facesw[i].indices[2]] );

		bvh_arrayw[i].face_index=i;
		bvh_arrayw[i].aabb=face_aabb;
		bvh_arrayw[i].center=face_aabb.pos+face_aabb.size*0.5;

	}

	w=DVector<Face>::Write();
	vw=DVector<Vector3>::Write();


	int count=0;
	_VolumeSW_BVH *bvh_tree=_volume_sw_build_bvh(bvh_arrayw,fc,count);

	ERR_FAIL_COND(count==0);

	bvhw=DVector<_VolumeSW_BVH_Element>::Write();

	bvh.resize( count+1 );

	DVector<BVH>::Write bvhw2 = bvh.write();
	BVH*bvh_arrayw2=bvhw2.ptr();

	int idx=0;
	_fill_bvh(bvh_tree,bvh_arrayw2,idx);

	set_aabb(_aabb);

#else
	DVector<_VolumeSW_BVH_Element> bvh_array;
	bvh_array.resize( src_face_count );

	DVector<_VolumeSW_BVH_Element>::Write bvhw = bvh_array.write();
	_VolumeSW_BVH_Element *bvh_arrayw=bvhw.ptr();

	faces.resize(src_face_count);
	DVector<Face>::Write w = faces.write();
	Face *facesw=w.ptr();

	vertices.resize( src_face_count*3 );

	DVector<Vector3>::Write vw = vertices.write();
	Vector3 *verticesw=vw.ptr();

	AABB _aabb;


	for(int i=0;i<src_face_count;i++) {

		Face3 face( facesr[i*3+0], facesr[i*3+1], facesr[i*3+2] );

		bvh_arrayw[i].aabb=face.get_aabb();
		bvh_arrayw[i].center = bvh_arrayw[i].aabb.pos + bvh_arrayw[i].aabb.size * 0.5;
		bvh_arrayw[i].face_index=i;
		facesw[i].indices[0]=i*3+0;
		facesw[i].indices[1]=i*3+1;
		facesw[i].indices[2]=i*3+2;
		facesw[i].normal=face.get_plane().normal;
		verticesw[i*3+0]=face.vertex[0];
		verticesw[i*3+1]=face.vertex[1];
		verticesw[i*3+2]=face.vertex[2];
		if (i==0)
			_aabb=bvh_arrayw[i].aabb;
		else
			_aabb.merge_with(bvh_arrayw[i].aabb);

	}

	w=DVector<Face>::Write();
	vw=DVector<Vector3>::Write();

	int count=0;
	_VolumeSW_BVH *bvh_tree=_volume_sw_build_bvh(bvh_arrayw,src_face_count,count);

	bvh.resize( count+1 );

	DVector<BVH>::Write bvhw2 = bvh.write();
	BVH*bvh_arrayw2=bvhw2.ptr();

	int idx=0;
	_fill_bvh(bvh_tree,bvh_arrayw2,idx);

	configure(_aabb); // this type of shape has no margin


#endif
}
Beispiel #10
0
AutoPtr<Elem> Hex8::build_side (const unsigned int i,
                                bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      AutoPtr<Elem> ap(new Side<Quad4,Hex8>(this,i));
      return ap;
    }

  else
    {
      AutoPtr<Elem> face(new Quad4);
      face->subdomain_id() = this->subdomain_id();

      // Think of a unit cube: (-1,1) x (-1,1)x (-1,1)
      switch (i)
        {
        case 0:  // the face at z = -1
          {
            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(3);
            face->set_node(2) = this->get_node(2);
            face->set_node(3) = this->get_node(1);

            return face;
          }
        case 1:  // the face at y = -1
          {
            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(1);
            face->set_node(2) = this->get_node(5);
            face->set_node(3) = this->get_node(4);

            return face;
          }
        case 2:  // the face at x = 1
          {
            face->set_node(0) = this->get_node(1);
            face->set_node(1) = this->get_node(2);
            face->set_node(2) = this->get_node(6);
            face->set_node(3) = this->get_node(5);

            return face;
          }
        case 3: // the face at y = 1
          {
            face->set_node(0) = this->get_node(2);
            face->set_node(1) = this->get_node(3);
            face->set_node(2) = this->get_node(7);
            face->set_node(3) = this->get_node(6);

            return face;
          }
        case 4: // the face at x = -1
          {
            face->set_node(0) = this->get_node(3);
            face->set_node(1) = this->get_node(0);
            face->set_node(2) = this->get_node(4);
            face->set_node(3) = this->get_node(7);

            return face;
          }
        case 5: // the face at z = 1
          {
            face->set_node(0) = this->get_node(4);
            face->set_node(1) = this->get_node(5);
            face->set_node(2) = this->get_node(6);
            face->set_node(3) = this->get_node(7);

            return face;
          }
        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  libmesh_error_msg("We'll never get here!");
  AutoPtr<Elem> ap(NULL);
  return ap;
}
Beispiel #11
0
AutoPtr<Elem> InfPrism12::build_side (const unsigned int i,
				      bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
	{
	  // base
	case 0:
	  {
	    AutoPtr<Elem> ap(new Side<Tri6,InfPrism12>(this,i));
	    return ap;
	  }
	  // ifem sides
	case 1:
	case 2:
	case 3:
	  {
	    AutoPtr<Elem> ap(new Side<InfQuad6,InfPrism12>(this,i));
	    return ap;
	  }
	default:
	  libmesh_error();
	}
    }

  else
    {
      switch (i)
	{
	case 0:  // the triangular face at z=-1, base face
	  {
	    AutoPtr<Elem> face(new Tri6);

	    // Note that for this face element, the normal points inward
	    face->set_node(0) = this->get_node(0);
	    face->set_node(1) = this->get_node(1);
	    face->set_node(2) = this->get_node(2);
	    face->set_node(3) = this->get_node(6);
	    face->set_node(4) = this->get_node(7);
	    face->set_node(5) = this->get_node(8);

	    return face;
	  }

	case 1:  // the quad face at y=0
	  {
	    AutoPtr<Elem> face(new InfQuad6);

	    face->set_node(0) = this->get_node(0);
	    face->set_node(1) = this->get_node(1);
	    face->set_node(2) = this->get_node(3);
	    face->set_node(3) = this->get_node(4);
	    face->set_node(4) = this->get_node(6);
	    face->set_node(5) = this->get_node(9);

	    return face;
	  }

	case 2:  // the other quad face
	  {
	    AutoPtr<Elem> face(new InfQuad6);

	    face->set_node(0) = this->get_node(1);
	    face->set_node(1) = this->get_node(2);
	    face->set_node(2) = this->get_node(4);
	    face->set_node(3) = this->get_node(5);
	    face->set_node(4) = this->get_node(7);
	    face->set_node(5) = this->get_node(10);

	    return face;
	  }

	case 3: // the quad face at x=0
	  {
	    AutoPtr<Elem> face(new InfQuad6);

	    face->set_node(0) = this->get_node(2);
	    face->set_node(1) = this->get_node(0);
	    face->set_node(2) = this->get_node(5);
	    face->set_node(3) = this->get_node(3);
	    face->set_node(4) = this->get_node(8);
	    face->set_node(5) = this->get_node(11);

	    return face;
	  }

	default:
	  {
	    libmesh_error();
	    AutoPtr<Elem> ap(NULL);  return ap;
	  }
	}
    }


  // We'll never get here.
  libmesh_error();
  AutoPtr<Elem> ap(NULL);  return ap;
}
Beispiel #12
0
int main(int argc, char **argv)
{
    face(argc, argv);
	return 0;
}
void RefineEverything(
	NodeVector & vecNodes,
	FaceVector & vecFaces,
	int nResolution
) {
	// Generate segment map
	SegmentMap mapSegment;
	ConstructSegmentMap(vecFaces, mapSegment, -1);

	FaceVector vecFacesOld = vecFaces;

	// Loop over all faces
	vecFaces.clear();

	// Construct map from segments to edges
	std::map<Segment, Edge> mapEdge;

	SegmentMapIterator iter = mapSegment.begin();
	for (; iter != mapSegment.end(); iter++) {
		Edge edge;

		GenerateEdgeVertices(
			nResolution,
			iter->first[0],
			iter->first[1],
			vecNodes,
			edge);

		mapEdge.insert(std::pair<Segment, Edge>(iter->first, edge));
	}

	// Loop over all faces and refine
	for (int n = 0 ; n < vecFacesOld.size(); n++) {
		const Segment & seg0 = vecFacesOld[n].iterSegment[0]->first;
		const Segment & seg1 = vecFacesOld[n].iterSegment[1]->first;
		const Segment & seg2 = vecFacesOld[n].iterSegment[2]->first;
		const Segment & seg3 = vecFacesOld[n].iterSegment[3]->first;

		Edge edge0 = mapEdge.find(seg0)->second;
		Edge edge1 = mapEdge.find(seg1)->second;
		Edge edge3 = mapEdge.find(seg2)->second;
		Edge edge2 = mapEdge.find(seg3)->second;

		// Align bottom and left edge
		if (edge0[0] == edge1[0]) {
		} else if (edge0[0] == edge1[edge1.size()-1]) {
			edge1 = edge1.Flip();
		} else if (edge0[edge0.size()-1] == edge1[0]) {
			edge0 = edge0.Flip();
		} else if (edge0[edge0.size()-1] == edge1[edge1.size()-1]) {
			edge0 = edge0.Flip();
			edge1 = edge1.Flip();
		} else {
			_EXCEPTIONT("Logic error");
		}

		// Align bottom and right edge
		if (edge0[edge0.size()-1] == edge2[0]) {
		} else if (edge0[edge0.size()-1] == edge2[edge2.size()-1]) {
			edge2 = edge2.Flip();
		} else {
			_EXCEPTIONT("Logic error");
		}

		// Align top and left edge
		if (edge1[edge1.size()-1] == edge3[0]) {
		} else if (edge1[edge1.size()-1] == edge3[edge3.size()-1]) {
			edge3 = edge3.Flip();
		} else {
			_EXCEPTIONT("Logic error");
		}

		Edge edgeTop;
		Edge edgeBot = edge0;

		for (int j = 0; j < nResolution; j++) {

			// Generate top level edge
			if (j != nResolution-1) {
				int ix0 = edge1[j+1];
				int ix1 = edge2[j+1];

				GenerateEdgeVertices(nResolution, ix0, ix1, vecNodes, edgeTop);

			} else {
				edgeTop = edge3;
			}

			// Generate face
			for (int i = 0; i < nResolution; i++) {
				Face face(
					edgeBot[i+1], edgeBot[i],
					edgeTop[i], edgeTop[i+1],
					vecFacesOld[n].nRefineLevel);

				face.nColor = vecFacesOld[n].nColor;
				face.nTag = vecFacesOld[n].nTag;

				vecFaces.push_back(face);
			}

			// Increment row
			edgeBot = edgeTop;
		}
	}
}
Beispiel #14
0
C3DModel CTriangulator<Real, Cylinder<Real> >::Triangulate(const Cylinder<Real> &pShape)
{

  Vector3<Real> center  = pShape.getCenter();
  Vector3<Real> u       = pShape.getU();
  Real height2           = pShape.getHalfLength();
  Real rad               = pShape.getRadius();

  C3DModel model;

  std::vector<Vector3<Real> > vVertices;
  std::vector<TriFace>         vFaces;

  int verticalsegments = 2;
  int pointsoncircle   = 24;

  Real dalpha = 2.0 * CMath<Real>::SYS_PI/(Real)pointsoncircle;

  Vector3<Real> vTop    = center + (height2 * u);
  Vector3<Real> vBottom = center - (height2 * u);
  vVertices.push_back(vTop);

  Real dheight = (2.0 * height2)/Real(verticalsegments+1);
  Real currentheight = center.z + height2;
  Real alpha = 0.0;

  //create the vertices
  for(int j=0;j<(verticalsegments+2);j++)
  {
    for(int i=0;i<pointsoncircle;i++)
    {
      Vector3<Real> vNext=pShape.eval(alpha);
      vNext.z = currentheight;
      vVertices.push_back(vNext);
      alpha+=dalpha;
    }
    alpha=0.0;
    currentheight-=dheight;
  }

  vVertices.push_back(vBottom);

  //add the top triangle fan
  for(int i=0;i<pointsoncircle;i++)
  {
    int verts[3];
    verts[0]=0;
    verts[1]=1+i;
    verts[2]=1+(i+1)%pointsoncircle;
    TriFace face(verts);
    vFaces.push_back(face);
  }

  //add the body of the cylinder
  int index = 1;
  for(int i=0;i<verticalsegments+1;i++)
  {
	  int index=1+i*pointsoncircle;
	  for(int j=0;j<pointsoncircle;j++)
	  {
	    int verts[3];
	    verts[0]=index+j;
	    verts[1]=index+pointsoncircle+j;
	    verts[2]=index+(j+1)%pointsoncircle;

	    TriFace face1(verts);
	    vFaces.push_back(face1);
	    verts[0]=index+(j+1)%pointsoncircle;
	    verts[1]=index+pointsoncircle+j;
	    verts[2]=index+pointsoncircle+(j+1)%pointsoncircle;
	    TriFace face2(verts);
	    vFaces.push_back(face2);
	  }
  }//end for i

  int ilast=vVertices.size()-1;
  int ilastrow=ilast-pointsoncircle;
  //add lower triangle fan
  for(int i=0;i<pointsoncircle;i++)
  {
	int verts[3];
	verts[0]=ilast;
	verts[1]=ilastrow+(i+1)%pointsoncircle;
	verts[2]=ilastrow+i;
	TriFace face(verts);
	vFaces.push_back(face);
  }

  model.CreateFrom(vVertices,vFaces);

  return model;

}
Beispiel #15
0
void
Surface_mesh::
remove_edge(Halfedge h)
{
    Halfedge  hn = next_halfedge(h);
    Halfedge  hp = prev_halfedge(h);

    Halfedge  o  = opposite_halfedge(h);
    Halfedge  on = next_halfedge(o);
    Halfedge  op = prev_halfedge(o);

    Face      fh = face(h);
    Face      fo = face(o);

    Vertex    vh = to_vertex(h);
    Vertex    vo = to_vertex(o);



    // halfedge -> vertex
    Halfedge_around_vertex_circulator vh_it, vh_end;
    vh_it = vh_end = halfedges(vo);
    do
    {
        set_vertex(opposite_halfedge(vh_it), vh);
    }
    while (++vh_it != vh_end);


    // halfedge -> halfedge
    set_next_halfedge(hp, hn);
    set_next_halfedge(op, on);


    // face -> halfedge
    if (fh.is_valid())  set_halfedge(fh, hn);
    if (fo.is_valid())  set_halfedge(fo, on);


    // vertex -> halfedge
    if (halfedge(vh) == o)  set_halfedge(vh, hn);
    adjust_outgoing_halfedge(vh);
    set_halfedge(vo, Halfedge());


    // delete stuff
    if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false);
    if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false);
    vdeleted_[vo]      = true; ++deleted_vertices_;
    edeleted_[edge(h)] = true; ++deleted_edges_;
    garbage_ = true;

    //add
    for(unsigned int j = 0;j < map_2skel.size();j++)
    {
        if(map_2skel[j] == vo.idx())
        {
            //unsigned int tem = map_2skel[j];
            map_2skel[j] = vh.idx();
            //qDebug("vertex:[%d],change %d to %d",j,tem,vh.idx());
        }
    }
    //end
}
Beispiel #16
0
int main(int, char const**)
{
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Minesweeper");

    // Set the Icon
    sf::Image icon;
    if (!icon.loadFromFile(resourcePath() + "icon.png")) {
        return EXIT_FAILURE;
    }
    window.setIcon(icon.getSize().x, icon.getSize().y, icon.getPixelsPtr());
    
    GameBoard gameBoard(COLUMNS, ROWS, MINES);
    
    CellTextures cellTextures;
    FaceTextures faceTextures;
    
    sf::RectangleShape backFill;
    backFill.setSize(sf::Vector2f(WINDOW_WIDTH, WINDOW_HEIGHT));
    backFill.setFillColor(sf::Color(164, 164, 164));

    sf::RectangleShape gridBorder;
    gridBorder.setPosition(sf::Vector2f(BOARD_X_OFFSET, BOARD_Y_OFFSET));
    gridBorder.setSize(sf::Vector2f(COLUMNS * CELL_WIDTH + 1, ROWS * CELL_HEIGHT + 1));
    gridBorder.setFillColor(sf::Color(86, 86, 86));
    
    int score = 0;
    
    sf::Font scoreFont;
    scoreFont.loadFromFile(resourcePath() + "sansation.ttf");
    sf::Text scoreCounter;
    scoreCounter.setPosition(BORDER, 0);
    scoreCounter.setColor(sf::Color::Black);
    scoreCounter.setFont(scoreFont);
    
    // Start the game loop
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::MouseButtonPressed) {
                int mouseX = event.mouseButton.x;
                int mouseY = event.mouseButton.y;
                
                int gridX = (mouseX - BOARD_X_OFFSET) / CELL_WIDTH;
                int gridY = (mouseY - BOARD_Y_OFFSET) / CELL_HEIGHT;
                
                if (gameBoard.validCoordinate(gridX, gridY)) {
                    if (event.mouseButton.button == sf::Mouse::Button::Left) {
                        score += gameBoard.onClick(gridX, gridY);
                    }
                    if (event.mouseButton.button == sf::Mouse::Button::Right) {
                        gameBoard.onRightClick(gridX, gridY);
                    }
                } else {
                    if (mouseX >= FACE_X && mouseX <= FACE_X + FACE_WIDTH &&
                        mouseY >= FACE_Y && mouseY <= FACE_Y + FACE_HEIGHT &&
                        event.mouseButton.button == sf::Mouse::Button::Left) {
                        /** RESTART GAME! */
                        score = 0;
                        gameBoard = GameBoard(COLUMNS, ROWS, MINES);
                    }
                }
            }
            
            // Close window : exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }

            // Escape pressed : exit
            if (event.type == sf::Event::KeyPressed &&
                event.key.code == sf::Keyboard::Escape) {
                window.close();
            }
        }

        // Clear screen
        window.clear();
        window.draw(backFill);
        window.draw(gridBorder);

        scoreCounter.setString(std::to_string(score));
        window.draw(scoreCounter);

        // Draw the grid
        for (int y = 0; y < gameBoard.getRows(); y++) {
            for (int x = 0; x < gameBoard.getColumns(); x++) {
                Cell cell = gameBoard.getCell(x, y);
                sf::Sprite sprite(*cellTextures.getCellTexture(cell, gameBoard.getNeighbouringMines(x, y)));
                sprite.setPosition(BOARD_X_OFFSET + x * CELL_WIDTH, BOARD_Y_OFFSET + y * CELL_HEIGHT);
                window.draw(sprite);
            }
        }
        
        // Draw the face
        sf::Sprite face(*(gameBoard.getIsGameOver() ? faceTextures.getLose() :
                          gameBoard.getIsGameWon() ? faceTextures.getWin() :
                          faceTextures.getPlaying()));
        face.setPosition(FACE_X, FACE_Y);
        window.draw(face);
 
        // Update the window
        window.display();
    }

    return EXIT_SUCCESS;
}
Beispiel #17
0
void
Surface_mesh::
garbage_collection()
{
    if (!garbage_) return;

    int  i, i0, i1,
    nV(vertices_size()),
    nE(edges_size()),
    nH(halfedges_size()),
    nF(faces_size());

    Vertex    v;
    Halfedge  h;
    Face      f;

    if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false);
    if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false);
    if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false);


    // setup handle mapping
    Vertex_property<Vertex>      vmap = add_vertex_property<Vertex>("v:garbage-collection");
    Halfedge_property<Halfedge>  hmap = add_halfedge_property<Halfedge>("h:garbage-collection");
    Face_property<Face>          fmap = add_face_property<Face>("f:garbage-collection");
    for (i=0; i<nV; ++i)
        vmap[Vertex(i)] = Vertex(i);
    for (i=0; i<nH; ++i)
        hmap[Halfedge(i)] = Halfedge(i);
    for (i=0; i<nF; ++i)
        fmap[Face(i)] = Face(i);



    // remove deleted vertices
    if (nV > 0)
    {
        i0=0;  i1=nV-1;

        while (1)
        {
            // find first deleted and last un-deleted
            while (!vdeleted_[Vertex(i0)] && i0 < i1)  ++i0;
            while ( vdeleted_[Vertex(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            vprops_.swap(i0, i1);

            //add
            for(unsigned int j = 0;j<map_2skel.size();j++)
            {
                if(map_2skel[j] == i0)
                    map_2skel[j] = i1;
                else if(map_2skel[j] == i1)
                    map_2skel[j] = i0;
            }
            //end
        };

        // remember new size
        nV = vdeleted_[Vertex(i0)] ? i0 : i0+1;
    }


    // remove deleted edges
    if (nE > 0)
    {
        i0=0;  i1=nE-1;

        while (1)
        {
            // find first deleted and last un-deleted
            while (!edeleted_[Edge(i0)] && i0 < i1)  ++i0;
            while ( edeleted_[Edge(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            eprops_.swap(i0, i1);
            hprops_.swap(2*i0,   2*i1);
            hprops_.swap(2*i0+1, 2*i1+1);
        };

        // remember new size
        nE = edeleted_[Edge(i0)] ? i0 : i0+1;
        nH = 2*nE;
    }


    // remove deleted faces
    if (nF > 0)
    {
        i0=0;  i1=nF-1;

        while (1)
        {
            // find 1st deleted and last un-deleted
            while (!fdeleted_[Face(i0)] && i0 < i1)  ++i0;
            while ( fdeleted_[Face(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            fprops_.swap(i0, i1);
        };

        // remember new size
        nF = fdeleted_[Face(i0)] ? i0 : i0+1;
    }


    // update vertex connectivity
    for (i=0; i<nV; ++i)
    {
        v = Vertex(i);
        if (!is_isolated(v))
            set_halfedge(v, hmap[halfedge(v)]);
    }


    // update halfedge connectivity
    for (i=0; i<nH; ++i)
    {
        h = Halfedge(i);
        set_vertex(h, vmap[to_vertex(h)]);
        set_next_halfedge(h, hmap[next_halfedge(h)]);
        if (!is_boundary(h))
            set_face(h, fmap[face(h)]);
    }


    // update handles of faces
    for (i=0; i<nF; ++i)
    {
        f = Face(i);
        set_halfedge(f, hmap[halfedge(f)]);
    }


    // remove handle maps
    remove_vertex_property(vmap);
    remove_halfedge_property(hmap);
    remove_face_property(fmap);


    // finally resize arrays
    vprops_.resize(nV); vprops_.free_memory();
    hprops_.resize(nH); hprops_.free_memory();
    eprops_.resize(nE); eprops_.free_memory();
    fprops_.resize(nF); fprops_.free_memory();

    deleted_vertices_ = deleted_edges_ = deleted_faces_ = 0;
    garbage_ = false;
}
Beispiel #18
0
const KHalfEdgeMesh::Face *KHalfEdgeMesh::unsafeFace(size_t idx) const
{
  return face(FaceIndex(static_cast<IndexType::index_type>(idx)));
}
Beispiel #19
0
/**
 * logic()
 * Handle a single frame.  This includes:
 * - move the avatar based on buttons pressed
 * - calculate the next frame of animation
 * - calculate camera position based on avatar position
 *
 * @param power_index The actionbar power activated.  -1 means no power.
 */
void Avatar::logic(int actionbar_power, bool restrictPowerUse) {

	Point target;
	int stepfx;
	stats.logic();
	if (stats.stun_duration > 0) return;
	bool allowed_to_move;
	bool allowed_to_use_power;
	
	// check level up
	int max_spendable_stat_points = 16;
	if (stats.xp >= stats.xp_table[stats.level] && stats.level < MAX_CHARACTER_LEVEL) {
		stats.level++;
		stringstream ss;
		ss << msg->get("Congratulations, you have reached level %d!", stats.level);
		if (stats.level < max_spendable_stat_points) {
			ss << " " << msg->get("You may increase one attribute through the Character Menu.");
            newLevelNotification = true;
		}
		log_msg = ss.str();
		stats.recalc();
		Mix_PlayChannel(-1, level_up, 0);
	}

	// check for bleeding spurt
	if (stats.bleed_duration % 30 == 1) {
		powers->activate(POWER_SPARK_BLOOD, &stats, stats.pos);
	}
	// check for bleeding to death
	if (stats.hp == 0 && !(stats.cur_state == AVATAR_DEAD)) {
		stats.cur_state = AVATAR_DEAD;
	}		
	
	// assist mouse movement
	if (!inp->pressing[MAIN1]) drag_walking = false;
	
	// handle animation
	activeAnimation->advanceFrame();
			
	switch(stats.cur_state) {
		case AVATAR_STANCE:

			setAnimation("stance");
		
			// allowed to move or use powers?
			if (MOUSE_MOVE) {
				allowed_to_move = restrictPowerUse && (!inp->lock[MAIN1] || drag_walking);
				allowed_to_use_power = !allowed_to_move;
			}
			else {
				allowed_to_move = true;
				allowed_to_use_power = true;
			}

			// handle transitions to RUN
			if (allowed_to_move)
				set_direction();
			
			if (pressing_move() && allowed_to_move) {
				if (MOUSE_MOVE && inp->pressing[MAIN1]) {
					inp->lock[MAIN1] = true;
					drag_walking = true;
				}
				
				if (move()) { // no collision
					stats.cur_state = AVATAR_RUN;
				}

			}
			// handle power usage
			if (allowed_to_use_power && actionbar_power != -1 && stats.cooldown_ticks == 0) {				
				target = screen_to_map(inp->mouse.x,  inp->mouse.y + powers->powers[actionbar_power].aim_assist, stats.pos.x, stats.pos.y);
			
				// check requirements
				if (powers->powers[actionbar_power].requires_mp > stats.mp)
					break;
				if (powers->powers[actionbar_power].requires_physical_weapon && !stats.wielding_physical)
					break;
				if (powers->powers[actionbar_power].requires_mental_weapon && !stats.wielding_mental)
					break;
				if (powers->powers[actionbar_power].requires_offense_weapon && !stats.wielding_offense)
					break;
				if (powers->powers[actionbar_power].requires_los && !map->collider.line_of_sight(stats.pos.x, stats.pos.y, target.x, target.y))
					break;
				if (powers->powers[actionbar_power].requires_empty_target && !map->collider.is_empty(target.x, target.y))
					break;
				if (stats.hero_cooldown[actionbar_power] > 0)
					break;

				stats.hero_cooldown[actionbar_power] = powers->powers[actionbar_power].cooldown; //set the cooldown timer
				current_power = actionbar_power;
				act_target.x = target.x;
				act_target.y = target.y;
			
				// is this a power that requires changing direction?
				if (powers->powers[current_power].face) {
					stats.direction = face(target.x, target.y);
				}
			
				// handle melee powers
				if (powers->powers[current_power].new_state == POWSTATE_SWING) {
					stats.cur_state = AVATAR_MELEE;
					break;
				}
				// handle ranged powers
				if (powers->powers[current_power].new_state == POWSTATE_SHOOT) {
					stats.cur_state = AVATAR_SHOOT;
					break;
				}
				// handle ment powers
				if (powers->powers[current_power].new_state == POWSTATE_CAST) {
					stats.cur_state = AVATAR_CAST;
					break;
				}
				if (powers->powers[current_power].new_state == POWSTATE_BLOCK) {
					stats.cur_state = AVATAR_BLOCK;
					stats.blocking = true;
					break;
				}
			}
			
			break;
			
		case AVATAR_RUN:

			setAnimation("run");
		
			stepfx = rand() % 4;
			
			if (activeAnimation->getCurFrame() == 1 || activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()/2) {
				Mix_PlayChannel(-1, sound_steps[stepfx], 0);
			}

			// allowed to move or use powers?
			if (MOUSE_MOVE) {
				allowed_to_use_power = !(restrictPowerUse && !inp->lock[MAIN1]);
			}
			else {
				allowed_to_use_power = true;
			}
			
			// handle direction changes
			set_direction();
			
			// handle transition to STANCE
			if (!pressing_move()) {
				stats.cur_state = AVATAR_STANCE;
				break;
			} 
			else if (!move()) { // collide with wall
				stats.cur_state = AVATAR_STANCE;
				break;
			}
						
			// handle power usage
			if (allowed_to_use_power && actionbar_power != -1 && stats.cooldown_ticks == 0) {

				target = screen_to_map(inp->mouse.x,  inp->mouse.y + powers->powers[actionbar_power].aim_assist, stats.pos.x, stats.pos.y);
			
				// check requirements
				if (powers->powers[actionbar_power].requires_mp > stats.mp)
					break;
				if (powers->powers[actionbar_power].requires_physical_weapon && !stats.wielding_physical)
					break;
				if (powers->powers[actionbar_power].requires_mental_weapon && !stats.wielding_mental)
					break;
				if (powers->powers[actionbar_power].requires_offense_weapon && !stats.wielding_offense)
					break;
				if (powers->powers[actionbar_power].requires_los && !map->collider.line_of_sight(stats.pos.x, stats.pos.y, target.x, target.y))
					break;
				if (powers->powers[actionbar_power].requires_empty_target && !map->collider.is_empty(target.x, target.y))
					break;
				if (stats.hero_cooldown[actionbar_power] > 0)
					break;

				stats.hero_cooldown[actionbar_power] = powers->powers[actionbar_power].cooldown; //set the cooldown timer
				current_power = actionbar_power;
				act_target.x = target.x;
				act_target.y = target.y;
			
				// is this a power that requires changing direction?
				if (powers->powers[current_power].face) {
					stats.direction = face(target.x, target.y);
				}
			
				// handle melee powers
				if (powers->powers[current_power].new_state == POWSTATE_SWING) {
					stats.cur_state = AVATAR_MELEE;
					break;
				}
				// handle ranged powers
				if (powers->powers[current_power].new_state == POWSTATE_SHOOT) {
					stats.cur_state = AVATAR_SHOOT;
					break;
				}
				// handle ment powers
				if (powers->powers[current_power].new_state == POWSTATE_CAST) {
					stats.cur_state = AVATAR_CAST;
					break;
				}
				if (powers->powers[current_power].new_state == POWSTATE_BLOCK) {
					stats.cur_state = AVATAR_BLOCK;
					stats.blocking = true;
					break;
				}				
			}
							
			break;
			
		case AVATAR_MELEE:

			setAnimation("melee");

			if (activeAnimation->getCurFrame() == 1) {
				Mix_PlayChannel(-1, sound_melee, 0);
			}
			
			// do power
			if (activeAnimation->getCurFrame()  == activeAnimation->getMaxFrame()/2) {
				powers->activate(current_power, &stats, act_target);
			}
			
			if (activeAnimation->getTimesPlayed() >= 1) {
				stats.cur_state = AVATAR_STANCE;
				if (stats.haste_duration == 0) stats.cooldown_ticks += stats.cooldown;
			}
			break;

		case AVATAR_CAST:

			setAnimation("ment");

			// do power
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()/2) {
				powers->activate(current_power, &stats, act_target);
			}

			if (activeAnimation->getTimesPlayed() >= 1) {
				stats.cur_state = AVATAR_STANCE;
				if (stats.haste_duration == 0) stats.cooldown_ticks += stats.cooldown;
			}
			break;

			
		case AVATAR_SHOOT:
		
			setAnimation("ranged");

			// do power
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()/2) {
				powers->activate(current_power, &stats, act_target);
			}

			if (activeAnimation->getTimesPlayed() >= 1) {
				stats.cur_state = AVATAR_STANCE;
				if (stats.haste_duration == 0) stats.cooldown_ticks += stats.cooldown;
			}
			break;

		case AVATAR_BLOCK:
		
			setAnimation("block");

			if (powers->powers[actionbar_power].new_state != POWSTATE_BLOCK) {
				stats.cur_state = AVATAR_STANCE;
				stats.blocking = false;
			}
			break;
			
		case AVATAR_HIT:

			setAnimation("hit");
						 
			if (activeAnimation->getTimesPlayed() >= 1) {
				stats.cur_state = AVATAR_STANCE;
			}
			
			break;
			
		case AVATAR_DEAD:

			setAnimation("die");
				
			if (activeAnimation->getCurFrame() == 1 && activeAnimation->getTimesPlayed() < 1) {
				Mix_PlayChannel(-1, sound_die, 0);
				log_msg = msg->get("You are defeated.  You lose half your gold.  Press Enter to continue.");
			}

			if (activeAnimation->getTimesPlayed() >= 1) {
				stats.corpse = true;
			}
			
			// allow respawn with Accept
			if (inp->pressing[ACCEPT]) {
				stats.hp = stats.maxhp;
				stats.mp = stats.maxmp;
				stats.alive = true;
				stats.corpse = false;
				stats.cur_state = AVATAR_STANCE;
				
				// remove temporary effects
				stats.clearEffects();
				
				// set teleportation variables.  GameEngine acts on these.
				map->teleportation = true;
				map->teleport_mapname = map->respawn_map;
				map->teleport_destination.x = map->respawn_point.x;
				map->teleport_destination.y = map->respawn_point.y;
			}
			
			break;
		
		default:
			break;
	}
	
	// calc new cam position from player position
	// cam is focused at player position
	map->cam.x = stats.pos.x;
	map->cam.y = stats.pos.y;
	map->hero_tile.x = stats.pos.x / 32;
	map->hero_tile.y = stats.pos.y / 32;
	
	// check for map events
	map->checkEvents(stats.pos);

	// decrement all cooldowns
	for (int i = 0; i < POWER_COUNT; i++){
		stats.hero_cooldown[i] -= 1000 / FRAMES_PER_SEC;
		if (stats.hero_cooldown[i] < 0) stats.hero_cooldown[i] = 0;
	}
}
Beispiel #20
0
int Face3Space::refine(hObj& f,const int)
{
	/// full break
	/// 0-3 - subfaces_, 4-6 - subedges_
	/// /*
	/// |\.
	/// |2 \.
	/// |    \.
	///  ---6--\.
	/// |\    3| \.
	/// |  4   5   \.
	/// |0___\_|____1\.   */

	Face3D & face( *static_cast<Face3D*>(&f) );
	face.updatePointers();
	assert(face.type_ == Face3D::myType);
	if(!face.isBroken())
	{
		hHybridMesh & m(*face.myMesh);
		face.mySize_= sizeof(Face3D);
		face.nMyClassSons_=4;

		assert(m.edges_.getById(face.components(0)).isBroken());
		assert(m.edges_.getById(face.components(1)).isBroken());
		assert(m.edges_.getById(face.components(2)).isBroken());
 
		const Vertex*	v[6]={ 
		    &m.vertices_[face.verts(0)],
		    &m.vertices_[face.verts(1)], 
		    &m.vertices_[face.verts(2)],
		    &m.vertices_.getById(m.edge(face.verts(0),face.verts(1)).sons(0)),
		    &m.vertices_.getById(m.edge(face.verts(0),face.verts(2)).sons(0)),
		    &m.vertices_.getById(m.edge(face.verts(1),face.verts(2)).sons(0)) };

		// new edges_
		// indexes of verts in v[6] for new edges
		static const int edgesVerts[3][2]={{3,4},{3,5},{4,5}};
		for(uTind i(0); i < 3; ++i)
		{
			const uTind vertices[2] ={ 
			v[ edgesVerts[i][0] ]->pos_,
			v[ edgesVerts[i][1] ]->pos_};
			Edge & child = *m.edges_.newObj<Edge>(vertices);
			child.parent_= face.id_;
			child.level_= face.level_+1;
			face.sons(i)=child.id_;
//			child.status(INACTIVE);
			child.components(0)=v[ edgesVerts[i][0] ]->id_;
			child.components(1)=v[ edgesVerts[i][1] ]->id_;
		}

		// new faces3
		// define vertices  building childrens
		const uTind verts[4][4]=
		{
			{v[0]->pos_,v[3]->pos_,v[4]->pos_,UNKNOWN},
			{v[3]->pos_,v[1]->pos_,v[5]->pos_,UNKNOWN},
			{v[4]->pos_,v[5]->pos_,v[2]->pos_,UNKNOWN},
			{// this one is flipped
			v[3]->pos_,v[5]->pos_,v[4]->pos_,UNKNOWN}
		};

		#ifdef _DEBUG		
				double parentNormVec[3]={0.0},
				  childNormVec[3]={0.0};
		  
				m.faceNormal(face,parentNormVec,NULL);
		#endif
		
		BYTE * adr( reinterpret_cast<BYTE*>(&face)+ face.mySize_);
		for(uTind i(0); i < 4; ++i)
		{
		  Face3 & faceChild =  *m.faces_.newObj<Face3>(verts[i],adr);
			faceChild.parent_= face.id_;
			faceChild.level_= face.level_+ 1;
//			faceChild.status(INACTIVE);
			adr += faceChild.mySize_;
			// code below is no more needed, as this is coverd in Face3 constructor
			//faceChild.components(0)=verts_n_comps[i][3  ];
			//faceChild.components(1)=verts_n_comps[i][3+1];
			//faceChild.components(2)=verts_n_comps[i][3+2];
			
			faceChild.neighs(0) = 0;
			faceChild.neighs(1) = 0;
			faceChild.flags(B_COND) = face.flags(B_COND);
			//faceChild.neighs(0) = face.neighs(0);
			//faceChild.neighs(1) = face.neighs(1);
			#ifdef _DEBUG
			m.faceNormal(faceChild, childNormVec,NULL);
			assert(abs(parentNormVec[0]-childNormVec[0]) <= SMALL);
			assert(abs(parentNormVec[1]-childNormVec[1]) <= SMALL);
			assert(abs(parentNormVec[2]-childNormVec[2]) <= SMALL);
			#endif
			
			if(i==3) { // fourth is flipped
			  faceChild.flags(F_TYPE)=F_FLIPPED;
			}
		}


#ifdef _DEBUG
		out_stream <<"\n refine Face3("<<face.pos_<<") "
			<<face.verts(0)<<" "
			<<face.verts(1)<<" "
			<<face.verts(2);
		for(int i(0); i < 3; ++i)
		{
			Face3 & faceChild = *face.getMyClassChild<Face3>(i);
			out_stream <<"\n child Face3("<<faceChild.pos_<<") : "
			<<faceChild.verts(0)<<" "
			<<faceChild.verts(1)<<" "
			<<faceChild.verts(2);
		}
#endif
	    ++(m.faces_.dividedObjs_);
	}
	return ( sizeof(Face3D) - sizeof(Face3) ) + 4*sizeof(Face3);
}
Beispiel #21
0
/**
 * logic()
 * Handle a single frame.  This includes:
 * - move the enemy based on AI % chances
 * - calculate the next frame of animation
 */
void Enemy::logic() {

	stats.logic();
	if (stats.stun_duration > 0) return;
	// check for bleeding to death
	if (stats.hp <= 0 && !(stats.cur_state == ENEMY_DEAD || stats.cur_state == ENEMY_CRITDEAD)) {
		doRewards();
		stats.cur_state = ENEMY_DEAD;
	}
	// check for bleeding spurt
	if (stats.bleed_duration % 30 == 1) {
		powers->activate(POWER_SPARK_BLOOD, &stats, stats.pos);
	}
	// check for teleport powers
	if (stats.teleportation) {
		stats.pos.x = stats.teleport_destination.x;
		stats.pos.y = stats.teleport_destination.y;	
		stats.teleportation = false;	
	}
	
	int dist;
	int prev_direction;
	bool los = false;
	Point pursue_pos;	
	//int max_frame;
	//int mid_frame;
	
	
	// SECTION 1: Steering and Vision
	// ------------------------------
	
	// check distance and line of sight between enemy and hero
	if (stats.hero_alive)
		dist = getDistance(stats.hero_pos);
	else
		dist = 0;
	
	// if the hero is too far away or dead, abandon combat and do nothing
	if (dist > stats.threat_range+stats.threat_range || !stats.hero_alive) {
		stats.in_combat = false;
		stats.patrol_ticks = 0;
		stats.last_seen.x = -1;
		stats.last_seen.y = -1;
	}

	if (dist < stats.threat_range && stats.hero_alive)
		los = map->collider.line_of_sight(stats.pos.x, stats.pos.y, stats.hero_pos.x, stats.hero_pos.y);
	else
		los = false;
		
	// if the enemy can see the hero, it pursues.
	// otherwise, it will head towards where it last saw the hero
	if (los && dist < stats.threat_range) {
		stats.in_combat = true;
		stats.last_seen.x = stats.hero_pos.x;
		stats.last_seen.y = stats.hero_pos.y;
	}
	else if (stats.last_seen.x >= 0 && stats.last_seen.y >= 0) {
		if (getDistance(stats.last_seen) <= (stats.speed+stats.speed) && stats.patrol_ticks == 0) {
			stats.last_seen.x = -1;
			stats.last_seen.y = -1;
			stats.patrol_ticks = 8; // start patrol; see note on "patrolling" below
		}		
	}
	

	
	// where is the creature heading?
	// TODO: add fleeing for X ticks
	if (los) {
		pursue_pos.x = stats.last_seen.x = stats.hero_pos.x;
		pursue_pos.y = stats.last_seen.y = stats.hero_pos.y;
		stats.patrol_ticks = 0;
	}
	else if (stats.in_combat) {
	
		// "patrolling" is a simple way to help steering.
		// When the enemy arrives at where he last saw the hero, it continues
		// walking a few steps.  This gives a better chance of re-establishing
		// line of sight around corners.
		
		if (stats.patrol_ticks > 0) {
			stats.patrol_ticks--;
			if (stats.patrol_ticks == 0) {
				stats.in_combat = false;
			}			
		}
		pursue_pos.x = stats.last_seen.x;
		pursue_pos.y = stats.last_seen.y;
	}


	
	// SECTION 2: States
	// -----------------
	
	activeAnimation->advanceFrame();

	switch(stats.cur_state) {
	
		case ENEMY_STANCE:
		
			setAnimation("stance");
			
			if (stats.in_combat) {

				// update direction to face the target
				if (++stats.dir_ticks > stats.dir_favor && stats.patrol_ticks == 0) {
					stats.direction = face(pursue_pos.x, pursue_pos.y);				
					stats.dir_ticks = 0;
				}
		
				// performed ranged actions
				if (dist > stats.melee_range && stats.cooldown_ticks == 0) {

					// CHECK: ranged physical!
					//if (!powers->powers[stats.power_index[RANGED_PHYS]].requires_los || los) {
					if (los) {
						if ((rand() % 100) < stats.power_chance[RANGED_PHYS] && stats.power_ticks[RANGED_PHYS] == 0) {
							
							newState(ENEMY_RANGED_PHYS);
							break;
						}
					}
					// CHECK: ranged spell!
					//if (!powers->powers[stats.power_index[RANGED_MENT]].requires_los || los) {
					if (los) {			
						if ((rand() % 100) < stats.power_index[RANGED_MENT] && stats.power_ticks[RANGED_MENT] == 0) {
							
							newState(ENEMY_RANGED_MENT);
							break;
						}
					}
				
					// CHECK: flee!
					
					// CHECK: pursue!
					if ((rand() % 100) < stats.chance_pursue) {
						if (move()) { // no collision
							newState(ENEMY_MOVE);
						}
						else {
							// hit an obstacle, try the next best angle
							prev_direction = stats.direction;
							stats.direction = faceNextBest(pursue_pos.x, pursue_pos.y);
							if (move()) {
								newState(ENEMY_MOVE);
								break;
							}
							else stats.direction = prev_direction;
						}
					}
					
				}
				// perform melee actions
				else if (dist <= stats.melee_range && stats.cooldown_ticks == 0) {
				
					// CHECK: melee attack!
					//if (!powers->powers[stats.power_index[MELEE_PHYS]].requires_los || los) {
					if (los) {
						if ((rand() % 100) < stats.power_chance[MELEE_PHYS] && stats.power_ticks[MELEE_PHYS] == 0) {
							
							newState(ENEMY_MELEE_PHYS);
							break;
						}
					}
					// CHECK: melee ment!
					//if (!powers->powers[stats.power_index[MELEE_MENT]].requires_los || los) {
					if (los) {
						if ((rand() % 100) < stats.power_chance[MELEE_MENT] && stats.power_ticks[MELEE_MENT] == 0) {
													
							newState(ENEMY_MELEE_MENT);
							break;
						}
					}
				}
			}
			
			break;
		
		case ENEMY_MOVE:
		
			setAnimation("run");
	
			if (stats.in_combat) {

				if (++stats.dir_ticks > stats.dir_favor && stats.patrol_ticks == 0) {
					stats.direction = face(pursue_pos.x, pursue_pos.y);				
					stats.dir_ticks = 0;
				}
				
				if (dist > stats.melee_range && stats.cooldown_ticks == 0) {
				
					// check ranged physical!
					//if (!powers->powers[stats.power_index[RANGED_PHYS]].requires_los || los) {
					if (los) {
						if ((rand() % 100) < stats.power_chance[RANGED_PHYS] && stats.power_ticks[RANGED_PHYS] == 0) {
							
							newState(ENEMY_RANGED_PHYS);
							break;
						}
					}
					// check ranged spell!
					// if (!powers->powers[stats.power_index[RANGED_MENT]].requires_los || los) {
					if (los) {
						if ((rand() % 100) < stats.power_chance[RANGED_MENT] && stats.power_ticks[RANGED_MENT] == 0) {
							
							newState(ENEMY_RANGED_MENT);
							break;
						}
					}
				
					if (!move()) {
						// hit an obstacle.  Try the next best angle
						prev_direction = stats.direction;
						stats.direction = faceNextBest(pursue_pos.x, pursue_pos.y);
						if (!move()) {
							newState(ENEMY_STANCE);
							stats.direction = prev_direction;
						}
					}
				}
				else {
					newState(ENEMY_STANCE);
				}
			}
			else {
				newState(ENEMY_STANCE);
			}
			break;
			
		case ENEMY_MELEE_PHYS:
			
			setAnimation("melee");

			if (activeAnimation->getCurFrame() == 1) {
				sfx_phys = true;
			}

			// the attack hazard is alive for a single frame
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()/2 && haz == NULL) {
				powers->activate(stats.power_index[MELEE_PHYS], &stats, pursue_pos);
				stats.power_ticks[MELEE_PHYS] = stats.power_cooldown[MELEE_PHYS];
			}

			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()-1) {
				newState(ENEMY_STANCE);
				stats.cooldown_ticks = stats.cooldown;
			}
			break;

		case ENEMY_RANGED_PHYS:

			setAnimation("ranged");
	
			// monsters turn to keep aim at the hero
			stats.direction = face(pursue_pos.x, pursue_pos.y);
			
			if (activeAnimation->getCurFrame() == 1) {
				sfx_phys = true;
			}
			
			// the attack hazard is alive for a single frame
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()/2 && haz == NULL) {
				powers->activate(stats.power_index[RANGED_PHYS], &stats, pursue_pos);
				stats.power_ticks[RANGED_PHYS] = stats.power_cooldown[RANGED_PHYS];
			}
			
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()-1) {
				newState(ENEMY_STANCE);
				stats.cooldown_ticks = stats.cooldown;
			}
			break;

		
		case ENEMY_MELEE_MENT:
	
			setAnimation("ment");

			if (activeAnimation->getCurFrame() == 1) {
				sfx_ment = true;
			}
			
			// the attack hazard is alive for a single frame
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()/2 && haz == NULL) {
				powers->activate(stats.power_index[MELEE_MENT], &stats, pursue_pos);
				stats.power_ticks[MELEE_MENT] = stats.power_cooldown[MELEE_MENT];
			}
			
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()-1) {
				newState(ENEMY_STANCE);
				stats.cooldown_ticks = stats.cooldown;
			}
			break;

		case ENEMY_RANGED_MENT:

			setAnimation("ment");
		
			// monsters turn to keep aim at the hero
			stats.direction = face(pursue_pos.x, pursue_pos.y);
	
			if (activeAnimation->getCurFrame() == 1) {
				sfx_ment = true;
			}
			
			// the attack hazard is alive for a single frame
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()/2 && haz == NULL) {
				powers->activate(stats.power_index[RANGED_MENT], &stats, pursue_pos);
				stats.power_ticks[RANGED_MENT] = stats.power_cooldown[RANGED_MENT];
			}
			
			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()-1) {
				newState(ENEMY_STANCE);
				stats.cooldown_ticks = stats.cooldown;
			}
			break;
	
		case ENEMY_HIT:
			// enemy has taken damage (but isn't dead)

			setAnimation("hit");
			if (activeAnimation->getCurFrame() == 1) {
				sfx_hit = true;
			}

			if (activeAnimation->getCurFrame() == activeAnimation->getMaxFrame()-1) {
				newState(ENEMY_STANCE);
			}
			
			break;
			
		case ENEMY_DEAD:

			// corpse means the creature is dead and done animating		
			if (!stats.corpse) {
				setAnimation("die");
				
				if (activeAnimation->getCurFrame() == 1) {
					sfx_die = true;
				}
            }

			break;
		
		case ENEMY_CRITDEAD:
			// critdead is an optional, more gruesome death animation
		
			// corpse means the creature is dead and done animating
			if (!stats.corpse) {
				setAnimation("critdie");
				
				if (activeAnimation->getCurFrame() == 1) {
					sfx_critdie = true;
				}
			}
			
			break;
	}

}
Beispiel #22
0
// static
bool OBJLoader::parseFace( int lineNumber, const std::string& line,
                          const std::vector< std::string >& tokens,
                          OBJGroup& currentGroup )
{
    // TODO: support negative indices.
    if( tokens.size() < 4 )
    {
        fprintf( stderr,
                "Incorrect number of tokens at line number: %d\n, %s\n",
                lineNumber, line.c_str() );
        return false;
    }
    // first check line consistency - each vertex in the face
    // should have the same number of attributes
    bool faceIsValid;
    bool faceHasTextureCoordinates;
    bool faceHasNormals;

    faceIsValid = OBJLoader::faceHasConsistentAttributes( tokens,
        &faceHasTextureCoordinates, &faceHasNormals );

    if( !faceIsValid )
    {
        fprintf( stderr, "Face attributes inconsistent at line number: %d\n%s\n",
                lineNumber, line.c_str() );
        return false;
    }

    // ensure that all faces in a group are consistent:
    // they either all have texture coordinates or they don't
    // they either all have normals or they don't
    //
    // check how many faces the current group has
    // if the group has no faces, then the first face sets the group attributes

    if( currentGroup.numFaces() == 0 )
    {
        currentGroup.setHasTextureCoordinates( faceHasTextureCoordinates );
        currentGroup.setHasNormals( faceHasNormals );
    }

    bool faceIsConsistentWithGroup =
        ( currentGroup.hasTextureCoordinates() == faceHasTextureCoordinates )
        && ( currentGroup.hasNormals() == faceHasNormals );

    if( !faceIsConsistentWithGroup )
    {
        // TODO: boolToString()
        fprintf( stderr,
                "Face attributes inconsistent with group: %s at line: %d\n%s\n",
                currentGroup.name().c_str(), lineNumber, line.c_str() );
        fprintf( stderr, "group.hasTextureCoordinates() = %d\n",
                currentGroup.hasTextureCoordinates() );
        fprintf( stderr, "face.hasTextureCoordinates() = %d\n",
                faceHasTextureCoordinates );
        fprintf( stderr, "group.hasNormals() = %d\n",
                currentGroup.hasNormals() );
        fprintf( stderr, "face.hasNormals() = %d\n", faceHasNormals );

        return false;
    }

    OBJFace face( faceHasTextureCoordinates, faceHasNormals );

    // Process each vertex.
    for( int i = 1; i < tokens.size(); ++i )
    {
        int vertexPositionIndex;
        int vertexTextureCoordinateIndex;
        int vertexNormalIndex;

        OBJLoader::getVertexAttributes( tokens[ i ],
            &vertexPositionIndex, &vertexTextureCoordinateIndex,
            &vertexNormalIndex );

        face.positionIndices().push_back( vertexPositionIndex - 1 );

        if( faceHasTextureCoordinates )
        {
            face.textureCoordinateIndices().push_back(
                vertexTextureCoordinateIndex - 1 );
        }
        if( faceHasNormals )
        {
            face.normalIndices().push_back( vertexNormalIndex - 1 );
        }
    }

    currentGroup.addFace( face );
    return true;
}
Beispiel #23
0
MagicCube::MagicCube():layer(0),Rotation3D(ORIGIN),history(this->getMagicCubeID()) {
    for (int i = 0; i < COUNTOFFACE; i++) {
        CubeFace face(static_cast<NAMEOFCOLOR>(i));
        this->cubeFace[i] = face;
    }
}
Beispiel #24
0
AutoPtr<Elem> InfHex16::build_side (const unsigned int i,
				    bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
	{
	  // base
	case 0:
	  {
	    AutoPtr<Elem> ap(new Side<Quad8,InfHex16>(this,i));
	    return ap;
	  }
	  // ifem sides
	case 1:
	case 2:
	case 3:
	case 4:
	  {
	    AutoPtr<Elem> ap(new Side<InfQuad6,InfHex16>(this,i));
	    return ap;
	  }
	default:
	  libmesh_error();
	}
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      AutoPtr<Elem> face(NULL);

      // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
      switch (i)
	{
	case 0: // the base face
	  {
            face.reset(new Quad8);

	    // Only here, the face element's normal points inward
	    face->set_node(0) = this->get_node(0);
	    face->set_node(1) = this->get_node(1);
	    face->set_node(2) = this->get_node(2);
	    face->set_node(3) = this->get_node(3);
	    face->set_node(4) = this->get_node(8);
	    face->set_node(5) = this->get_node(9);
	    face->set_node(6) = this->get_node(10);
	    face->set_node(7) = this->get_node(11);

	    break;
	  }

	case 1:  // connecting to another infinite element
	  {
            face.reset(new InfQuad6);

	    face->set_node(0) = this->get_node(0);
	    face->set_node(1) = this->get_node(1);
	    face->set_node(2) = this->get_node(4);
	    face->set_node(3) = this->get_node(5);
	    face->set_node(4) = this->get_node(8);
	    face->set_node(5) = this->get_node(12);

	    break;
	  }

	case 2:  // connecting to another infinite element
	  {
            face.reset(new InfQuad6);

	    face->set_node(0) = this->get_node(1);
	    face->set_node(1) = this->get_node(2);
	    face->set_node(2) = this->get_node(5);
	    face->set_node(3) = this->get_node(6);
	    face->set_node(4) = this->get_node(9);
	    face->set_node(5) = this->get_node(13);

	    break;
	  }

	case 3:  // connecting to another infinite element
	  {
            face.reset(new InfQuad6);

	    face->set_node(0) = this->get_node(2);
	    face->set_node(1) = this->get_node(3);
	    face->set_node(2) = this->get_node(6);
	    face->set_node(3) = this->get_node(7);
	    face->set_node(4) = this->get_node(10);
	    face->set_node(5) = this->get_node(14);

	    break;
	  }

	case 4:  // connecting to another infinite element
	  {
            face.reset(new InfQuad6);

	    face->set_node(0) = this->get_node(3);
	    face->set_node(1) = this->get_node(0);
	    face->set_node(2) = this->get_node(7);
	    face->set_node(3) = this->get_node(4);
	    face->set_node(4) = this->get_node(11);
	    face->set_node(5) = this->get_node(15);

	    break;
	  }

	default:
	  {
	    libmesh_error();
	  }
	}

      face->subdomain_id() = this->subdomain_id();
      return face;
    }


  // We'll never get here.
  libmesh_error();
  AutoPtr<Elem> ap(NULL);  return ap;
}
// Calculate area in contact given displacement of vertices relative to
// the face plane. Positive displacement is above the face (no contact);
// negative is in contact
Foam::scalar Foam::face::areaInContact
(
    const pointField& meshPoints,
    const scalarField& v
) const
{
    // Assemble the vertex values
    const labelList& labels = *this;

    scalarField vertexValue(labels.size());

    forAll (labels, i)
    {
        vertexValue[i] = v[labels[i]];
    }


    // Loop through vertexValue. If all greater that 0 return 0 (no contact);
    // if all less than zero return 1
    // all zeros is assumed to be in contact.

    bool allPositive = true;
    bool allNegative = true;

    forAll (vertexValue, vI)
    {
        if (vertexValue[vI] > 0)
        {
            allNegative = false;
        }
        else
        {
            allPositive = false;
        }
    }

    if (allPositive)
    {
        return 0.0;
    }

    if (allNegative)
    {
        return 1.0;
    }

    // There is a partial contact.
    // Algorithm:
    // Go through all edges. if both vertex values for the edge are
    // positive, discard. If one is positive and one is negative,
    // create a point and start the edge with it. If both are
    // negative, add the edge into the new face.  When finished,
    // calculate area of new face and return relative area (0<x<1)

    // Dimension new point list to max possible size
    const labelList& faceLabels = *this;

    pointField newFacePoints(2*size());
    label nNewFacePoints = 0;

    for (label vI = 0; vI < size() - 1; vI++)
    {
        if (vertexValue[vI] <= 0)
        {
            // This is a point in contact
            newFacePoints[nNewFacePoints] = meshPoints[faceLabels[vI]];
            nNewFacePoints++;
        }

        if
        (
            (vertexValue[vI] > 0 && vertexValue[vI + 1] < 0)
         || (vertexValue[vI] < 0 && vertexValue[vI + 1] > 0)
        )
        {
            // Edge intersection. Calculate intersection point and add to list
            point intersection =
                meshPoints[faceLabels[vI]]
              + vertexValue[vI]/(vertexValue[vI + 1] - vertexValue[vI])
                *(meshPoints[faceLabels[vI]] - meshPoints[faceLabels[vI + 1]]);

            newFacePoints[nNewFacePoints] = intersection;
            nNewFacePoints++;
        }
    }

    // Do last point by hand
    if (vertexValue[size() - 1] <= 0)
    {
        // This is a point in contact
        newFacePoints[nNewFacePoints] = meshPoints[faceLabels[size() - 1]];
        nNewFacePoints++;
    }

    if
    (
        (vertexValue[size() - 1] > 0 && vertexValue[0] < 0)
     || (vertexValue[size() - 1] < 0 && vertexValue[0] > 0)
    )
    {
        // Edge intersection. Calculate intersection point and add to list
        point intersection =
            meshPoints[faceLabels[size() - 1]]
          + vertexValue[size() - 1]/(vertexValue[0] - vertexValue[size() - 1])
            *(meshPoints[faceLabels[size() - 1]] - meshPoints[faceLabels[0]]);

        newFacePoints[nNewFacePoints] = intersection;
        nNewFacePoints++;
    }

    newFacePoints.setSize(nNewFacePoints);

    // Make a labelList for the sub-face (points are ordered!)
    labelList sfl(newFacePoints.size());

    forAll (sfl, sflI)
    {
        sfl[sflI] = sflI;
    }

    // Calculate relative area
    return face(sfl).mag(newFacePoints)/(mag(meshPoints) + VSMALL);
}
Beispiel #26
0
void StrandBlockSolver::rhsViscousFine()
{
  int c1,c2,n1,n2,fc,jm,jp,npts=1;
  double dx1,dy1,dx2,dy2,ds,dq1,dq2,eps=1.e-14,
    qxe[nq],qye[nq],qaxe[nqa],qaye[nqa],qe[nq],qae[nqa],fv[nq];


  // unstructured faces
  for (int n=0; n<nEdges; n++){
    c1             = edge(0,n);
    c2             = edge(1,n);
    n1             = edgn(n);
    fc             = fClip(c1);
    if (fClip(c2) > fc) fc = fClip(c2);
    for (int j=1; j<fc+1; j++){
      jm           = j-1;
      dx1          = x (0,j,n1)-x (0,jm,n1);
      dy1          = x (1,j,n1)-x (1,jm,n1);
      dx2          = xc(0,j,c2)-xc(0,j ,c1);
      dy2          = xc(1,j,c2)-xc(1,j ,c1);
      ds           = 1./(dx1*dy2-dx2*dy1);
      for (int k=0; k<nq; k++){
	dq1        = qp(k,j,n1)-qp(k,jm,n1);
	dq2        = q (k,j,c2)-q (k,j ,c1);
	qxe[k]     = ds*( dy2*dq1-dy1*dq2);
	qye[k]     = ds*(-dx2*dq1+dx1*dq2);
	qe[k]      = .5*(qp (k,j,n1)+qp (k,jm,n1));
      }
      for (int k=0; k<nqa; k++){
	dq1        = qap(k,j,n1)-qap(k,jm,n1);
	dq2        = qa (k,j,c2)-qa (k,j ,c1);
	qaxe[k]    = ds*( dy2*dq1-dy1*dq2);
	qaye[k]    = ds*(-dx2*dq1+dx1*dq2);
	qae[k]     = .5*(qap(k,j,n1)+qap(k,jm,n1));
      }
      sys->rhsVisFlux(npts,&facs(0,j,n),&qe[0],&qae[0],&qxe[0],&qye[0],
		      &qaxe[0],&qaye[0],&fv[0]);
      for (int k=0; k<nq; k++){
	r(k,j,c1) -= fv[k];
	r(k,j,c2) += fv[k];
      }}}


  // structured faces
  for (int n=0; n<nFaces-nGfaces; n++){
    n1             = face(0,n);
    n2             = face(1,n);
    for (int j=0; j<fClip(n)+1; j++){
      jp           = j+1;
      dx1          = x (0,j ,n2)-x (0,j,n1);
      dy1          = x (1,j ,n2)-x (1,j,n1);
      dx2          = xc(0,jp,n )-xc(0,j,n );
      dy2          = xc(1,jp,n )-xc(1,j,n );
      ds           = dx1*dy2-dx2*dy1;
      if (fabs(ds) < eps) for (int k=0; k<nq; k++) fv[k] = 0.;
      else{
	ds         = 1./ds;
	for (int k=0; k<nq; k++){
	  dq1      = qp(k,j ,n2)-qp(k,j,n1);
	  dq2      = q (k,jp,n )-q (k,j,n );
	  qxe[k]   = ds*( dy2*dq1-dy1*dq2);
	  qye[k]   = ds*(-dx2*dq1+dx1*dq2);
	  qe[k]    = .5*(qp (k,j,n1)+qp (k,j,n2));
	}
	for (int k=0; k<nqa; k++){
	  dq1      = qap(k,j ,n2)-qap(k,j,n1);
	  dq2      = qa (k,jp,n )-qa (k,j,n );
	  qaxe[k]  = ds*( dy2*dq1-dy1*dq2);
	  qaye[k]  = ds*(-dx2*dq1+dx1*dq2);
	  qae[k]   = .5*(qap(k,j,n1)+qap(k,j,n2));
	}
	sys->rhsVisFlux(npts,&facu(0,j,n),&qe[0],&qae[0],&qxe[0],&qye[0],
			&qaxe[0],&qaye[0],&fv[0]);
      }
      for (int k=0; k<nq; k++){
	r(k,j ,n) -= fv[k];
	r(k,jp,n) += fv[k];
      }}}
}
Beispiel #27
0
 const Vector& normal_of_vertex_of_face(size_t v, size_t f) const
 { return normal(face(f)(v)); }
Beispiel #28
0
// This routine assumes the sentinel points have already been added, and processes points in order
GEODE_NEVER_INLINE static Ref<MutableTriangleTopology> deterministic_exact_delaunay(RawField<const Perturbed2,VertexId> X, const bool validate) {

  const int n = X.size()-3;
  const auto mesh = new_<MutableTriangleTopology>();
  IntervalScope scope;

  // Initialize the mesh to a Delaunay triangle containing the sentinels at infinity.
  mesh->add_vertices(n+3);
  mesh->add_face(vec(VertexId(n+0),VertexId(n+1),VertexId(n+2)));
  if (self_check) {
    mesh->assert_consistent();
    assert_delaunay("self check 0: ",mesh,X);
  }

  // The randomized incremental construction algorithm uses the history of the triangles
  // as the acceleration structure.  Specifically, we maintain a BSP tree where the nodes
  // are edge tests (are we only the left or right of an edge) and the leaves are triangles.
  // There are two operations that modify this tree:
  //
  // 1. Split: A face is split into three by the insertion of an interior vertex.
  // 2. Flip: An edge is flipped, turning two triangles into two different triangles.
  //
  // The three starts out empty, since one triangle needs zero tests.
  Array<Node> bsp; // All BSP nodes including leaves
  bsp.preallocate(3*n); // The minimum number of possible BSP nodes
  Field<Vector<int,2>,FaceId> face_to_bsp; // Map from FaceId to up to two BSP leaf points (2*node+(right?0:1))
  face_to_bsp.flat.preallocate(2*n+1); // The exact maximum number of faces
  face_to_bsp.flat.append_assuming_enough_space(vec(0,-1)); // By the time we call set_links, node 0 will be valid
  if (self_check)
    check_bsp(*mesh,bsp,face_to_bsp,X);

  // Allocate a stack to simulate recursion when flipping non-Delaunay edges.
  // Invariant: if edge is on the stack, the other edges of face(edge) are Delaunay.
  // Since halfedge ids change during edge flips in a corner mesh, we store half edges as directed vertex pairs.
  Array<Tuple<HalfedgeId,Vector<VertexId,2>>> stack;
  stack.preallocate(8);

  // Insert all vertices into the mesh in random order, maintaining the Delaunay property
  for (const auto i : range(n)) {
    const VertexId v(i);
    check_interrupts();

    // Search through the BSP tree to find the containing triangle
    const auto f0 = bsp_search(bsp,X,v);
    const auto vs = mesh->vertices(f0);

    // Split the face by inserting the new vertex and update the BSP tree accordingly.
    mesh->split_face(f0,v);
    const auto e0 = mesh->halfedge(v),
               e1 = mesh->left(e0),
               e2 = mesh->right(e0);
    assert(mesh->dst(e0)==vs.x);
    const auto f1 = mesh->face(e1),
               f2 = mesh->face(e2);
    const int base = bsp.extend(3,uninit);
    set_links(bsp,face_to_bsp[f0],base);
    bsp[base+0] = Node(vec(v,vs.x),base+2,base+1);
    bsp[base+1] = Node(vec(v,vs.y),~f0.id,~f1.id);
    bsp[base+2] = Node(vec(v,vs.z),~f1.id,~f2.id);
    face_to_bsp[f0] = vec(2*(base+1)+0,-1);
    face_to_bsp.flat.append_assuming_enough_space(vec(2*(base+1)+1,2*(base+2)+0));
    face_to_bsp.flat.append_assuming_enough_space(vec(2*(base+2)+1,-1));
    if (self_check) {
      mesh->assert_consistent();
      check_bsp(*mesh,bsp,face_to_bsp,X);
    }

    // Fix all non-Delaunay edges
    stack.copy(vec(tuple(mesh->next(e0),vec(vs.x,vs.y)),
                   tuple(mesh->next(e1),vec(vs.y,vs.z)),
                   tuple(mesh->next(e2),vec(vs.z,vs.x))));
    if (self_check)
      assert_delaunay("self check 1: ",mesh,X,Tuple<>(),true);
    while (stack.size()) {
      const auto evs = stack.pop();
      auto e = mesh->vertices(evs.x)==evs.y ? evs.x : mesh->halfedge(evs.y.x,evs.y.y);
      if (e.valid() && !is_delaunay(*mesh,X,e)) {
        // Our mesh is linearly embedded in the plane, so edge flips are always safe
        assert(mesh->is_flip_safe(e));
        e = mesh->unsafe_flip_edge(e);
        GEODE_ASSERT(is_delaunay(*mesh,X,e));
        // Update the BSP tree for the triangle flip
        const auto f0 = mesh->face(e),
                   f1 = mesh->face(mesh->reverse(e));
        const int node = bsp.append(Node(mesh->vertices(e),~f1.id,~f0.id));
        set_links(bsp,face_to_bsp[f0],node);
        set_links(bsp,face_to_bsp[f1],node);
        face_to_bsp[f0] = vec(2*node+1,-1);
        face_to_bsp[f1] = vec(2*node+0,-1);
        if (self_check) {
          mesh->assert_consistent();
          check_bsp(*mesh,bsp,face_to_bsp,X);
        }
        // Recurse to successor edges to e
        const auto e0 = mesh->next(e),
                   e1 = mesh->prev(mesh->reverse(e));
        stack.extend(vec(tuple(e0,mesh->vertices(e0)),
                         tuple(e1,mesh->vertices(e1))));
        if (self_check)
          assert_delaunay("self check 2: ",mesh,X,Tuple<>(),true);
      }
    }
    if (self_check) {
      mesh->assert_consistent();
      assert_delaunay("self check 3: ",mesh,X);
    }
  }

  // Remove sentinels
  for (int i=0;i<3;i++)
    mesh->erase_last_vertex_with_reordering();

  // If desired, check that the final mesh is Delaunay
  if (validate)
    assert_delaunay("delaunay validate: ",mesh,X);

  // Return the mesh with the sentinels removed
  return mesh;
}
Beispiel #29
0
// static
bool OBJLoader::parseFace( int lineNumber, QString line,
						  QStringList tokens, OBJGroup* pCurrentGroup )
{
	// HACK
	/*
	if( tokens.size() < 4 )
	{
		fprintf( stderr, "Incorrect number of tokens at line number: %d\n, %s\n",
			lineNumber, qPrintable( line ) );
		return false;
	}
	else
	*/
	{
		// first check line consistency - each vertex in the face
		// should have the same number of attributes

		// HACK
		bool faceIsValid = true;
		bool faceHasTextureCoordinates = false;
		bool faceHasNormals = true;
		/*
		bool faceIsValid;
		bool faceHasTextureCoordinates;
		bool faceHasNormals;

		faceIsValid = OBJLoader::isFaceLineAttributesConsistent( tokens,
			&faceHasTextureCoordinates, &faceHasNormals );

		if( !faceIsValid )
		{
			fprintf( stderr, "Face attributes inconsistent at line number: %d\n%s\n",
				lineNumber, qPrintable( line ) );
			return false;
		}
		*/

		// ensure that all faces in a group are consistent
		// they either all have texture coordinates or they don't
		// they either all have normals or they don't
		// 
		// check how many faces the current group has
		// if the group has no faces, then the first vertex sets it

		if( pCurrentGroup->getFaces()->size() == 0 )
		{
			pCurrentGroup->setHasTextureCoordinates( faceHasTextureCoordinates );
			pCurrentGroup->setHasNormals( faceHasNormals );
		}

		bool faceIsConsistentWithGroup = ( pCurrentGroup->hasTextureCoordinates() == faceHasTextureCoordinates ) &&
			( pCurrentGroup->hasNormals() == faceHasNormals );

		if( !faceIsConsistentWithGroup )
		{
			fprintf( stderr, "Face attributes inconsistent with group: %s at line: %d\n%s\n",
				qPrintable( pCurrentGroup->name() ), lineNumber, qPrintable( line ) );
			fprintf( stderr, "group.hasTextureCoordinates() = %d\n", pCurrentGroup->hasTextureCoordinates() );
			fprintf( stderr, "face.hasTextureCoordinates() = %d\n", faceHasTextureCoordinates );
			fprintf( stderr, "group.hasNormals() = %d\n", pCurrentGroup->hasNormals() );
			fprintf( stderr, "face.hasNormals() = %d\n", faceHasNormals );
			
			return false;
		}

		OBJFace face( faceHasTextureCoordinates, faceHasNormals );

		// for each vertex
		for( int i = 1; i < tokens.size(); ++i )
		{
			int vertexPositionIndex;
			int vertexTextureCoordinateIndex;
			int vertexNormalIndex;

			OBJLoader::getVertexAttributes( tokens[ i ],
				&vertexPositionIndex, &vertexTextureCoordinateIndex, &vertexNormalIndex );

			face.getPositionIndices()->append( vertexPositionIndex );

			if( faceHasTextureCoordinates )
			{
				face.getTextureCoordinateIndices()->append( vertexTextureCoordinateIndex );
			}
			if( faceHasNormals )
			{
				face.getNormalIndices()->append( vertexNormalIndex );
			}
		}

		pCurrentGroup->addFace( face );
		return true;
	}
}
Beispiel #30
0
C3DModel CTriangulator<Real, Ellipsoid<Real> >::Triangulate(const Ellipsoid<Real> &pShape)
{
  //-Pi/2 to Pi/2
  Real phi;
  //0 to 2Pi
  Real theta;
  //points on the sphere
  //x=x0+r*cos(theta)*cos(phi)
  //y=y0+r*cos(theta)*sin(phi)
  //z=z0+r*sin(theta)

  C3DModel model;

  std::vector<Vector3<Real> > vVertices;
  std::vector<TriFace>         vFaces;

  int lat  =8;
  int longi=8;

  Real dphi   = CMath<Real>::SYS_PI/(Real)longi;
  Real dtheta = CMath<Real>::SYS_PI/(Real)lat;
  Real halfpi = CMath<Real>::SYS_PI/2.0;

  Vector3<Real> vTop=pShape.eval(halfpi,0);
  Vector3<Real> vBottom=pShape.eval(-halfpi,0);
  vVertices.push_back(vTop);
  
  phi  = halfpi-dphi;
  for(int j=1;j<longi;j++)
  {

	theta=0.0f;
	for(int i=0;i<2*lat;i++)
	{
	  Vector3<Real> vNext=pShape.eval(phi,theta);
	  vVertices.push_back(vNext);
	  theta+=dtheta;
	}//end for i
	phi-=dphi;
  }//end for j

  vVertices.push_back(vBottom);

 // for(int i=0;i<vVertices.size();i++)
	//cout<<vVertices[i]<<endl;

  int lat2=2*lat;
  //add upper triangle fan
  for(int i=0;i<lat2;i++)
  {
	int verts[3];
	verts[0]=0;
	verts[1]=1+i;
	verts[2]=1+(i+1)%lat2;
	TriFace face(verts);
	vFaces.push_back(face);
  }

  //add body
  for(int i=0;i<longi-2;i++)
  {
	int index=1+i*lat2;
	for(int j=0;j<lat2;j++)
	{
	  int verts[3];
	  verts[0]=index+j;
	  verts[1]=index+lat2+j;
	  verts[2]=index+(j+1)%lat2;

	  TriFace face1(verts);
	  vFaces.push_back(face1);
	  verts[0]=index+(j+1)%lat2;
	  verts[1]=index+lat2+j;
	  verts[2]=index+lat2+(j+1)%lat2;
	  TriFace face2(verts);
	  vFaces.push_back(face2);
	}
  }
  int ilast=vVertices.size()-1;
  int ilastrow=ilast-lat2;
  //add lower triangle fan
  for(int i=0;i<lat2;i++)
  {
	int verts[3];
	verts[0]=ilast;
	verts[1]=ilastrow+(i+1)%lat2;
	verts[2]=ilastrow+i;
	TriFace face(verts);
	vFaces.push_back(face);
  }

  model.CreateFrom(vVertices,vFaces);

  return model;
}