Пример #1
0
void Controller::displayDensityCurves(int x, int y)
{
	SteerableViewMap * svm = _Canvas->getSteerableViewMap();
	if (!svm)
		return;

	unsigned int i, j;
	typedef vector<Vec3r> densityCurve;
	vector<densityCurve> curves(svm->getNumberOfOrientations() + 1);
	vector<densityCurve> curvesDirection(svm->getNumberOfPyramidLevels());

	// collect the curves values
	unsigned nbCurves = svm->getNumberOfOrientations() + 1;
	unsigned nbPoints = svm->getNumberOfPyramidLevels();
	if (!nbPoints)
		return;

	// build the density/nbLevels curves for each orientation
	for (i = 0; i < nbCurves; ++i) {
		for (j = 0; j < nbPoints; ++j) {
			curves[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(i, j, x, y), 0));
		}
	}
	// build the density/nbOrientations curves for each level
	for (i = 0; i < nbPoints; ++i) {
		for (j = 0; j < nbCurves; ++j) {
			curvesDirection[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(j, i, x, y), 0));
		}
	}

	// display the curves
#if 0
	for (i = 0; i < nbCurves; ++i)
		_pDensityCurvesWindow->setOrientationCurve(i, Vec2d(0, 0), Vec2d(nbPoints, 1), curves[i], "scale", "density");
	for (i = 1; i <= 8; ++i)
		_pDensityCurvesWindow->setLevelCurve(i, Vec2d(0, 0), Vec2d(nbCurves, 1), curvesDirection[i],
		                                     "orientation", "density");
	_pDensityCurvesWindow->show();
#endif
}
Пример #2
0
void IndexedFaceSet::ComputeBBox()
{
    real XMax = _Vertices[0];
    real YMax = _Vertices[1];
    real ZMax = _Vertices[2];

    real XMin = _Vertices[0];
    real YMin = _Vertices[1];
    real ZMin = _Vertices[2];

    // parse all the coordinates to find
    // the Xmax, YMax, ZMax
    real *v = _Vertices;

    for(unsigned i=0; i<_VSize/3; i++)
    {
        // X
        if(*v > XMax)
            XMax = *v;
        if(*v < XMin)
            XMin = *v;
        v++;

        if(*v > YMax)
            YMax = *v;
        if(*v < YMin)
            YMin = *v;
        v++;

        if(*v > ZMax)
            ZMax = *v;
        if(*v < ZMin)
            ZMin = *v;
        v++;
    }

    SetBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax)));
}
/*! Calculates \a matWorldToLight and \a matEyeToLight for a directional light
    \a dirL and inverse viewing matrix \a matEyeToWorld.
*/
void ShaderShadowMapEngine::calcDirectionalLightMatrices(
    Matrixr          &matWorldToLight,
    Matrixr          &matEyeToLight,
    const DirectionalLight *dirL,
    const Matrixr          &matEyeToWorld)
{
    if(dirL->getBeacon() != NULL)
        dirL->getBeacon()->getToWorld(matWorldToLight);

    Quaternion rotLightDir  (Vec3r(0.f, 0.f, 1.f), dirL->getDirection());
    Matrixr    matLightDir;
    matLightDir.setRotate(rotLightDir);

    matWorldToLight.mult  (matLightDir);
    matWorldToLight.invert(           );

    matEyeToLight = matWorldToLight;
    matEyeToLight.mult(matEyeToWorld);
}
Пример #4
0
Polygon3r* Grid::castRayToFindFirstIntersection(const Vec3r& orig,
                   const Vec3r& dir,
                   double& t,
                   double& u,
                   double& v,
                   unsigned timestamp){
    Polygon3r *occluder = 0;
    Vec3r end = Vec3r(orig + FLT_MAX * dir / dir.norm());
    bool inter = initInfiniteRay(orig, dir, timestamp);
    if(!inter){
        return 0;
    }
    firstIntersectionGridVisitor visitor(orig,dir,_cell_size);
    castRayInternal(visitor);
    occluder = visitor.occluder();
    t = visitor.t_;
    u = visitor.u_;
    v = visitor.v_;
    return occluder;
}
/*! Calculates \a matWorldToLight and \a matEyeToLight for a spot light
    \a spotL and inverse viewing matrix \a matEyeToWorld.
*/
void ShaderShadowMapEngine::calcSpotLightMatrices(
    Matrixr   &matWorldToLight,
    Matrixr   &matEyeToLight,
    const SpotLight *spotL,
    const Matrixr   &matEyeToWorld)
{
    if(spotL->getBeacon() != NULL)
        spotL->getBeacon()->getToWorld(matWorldToLight);

    Matrixr matLightPos;
    matLightPos.setTranslate(spotL->getPosition());

    Matrixr    matLightDir;
    Quaternion rotLightDir(Vec3r(0.f, 0.f, 1.f), -spotL->getDirection());
    matLightDir.setRotate(rotLightDir);

    matWorldToLight.mult  (matLightPos);
    matWorldToLight.mult  (matLightDir);
    matWorldToLight.invert(           );

    matEyeToLight = matWorldToLight;
    matEyeToLight.mult(matEyeToWorld);
}
Пример #6
0
void WFillGrid::addShape(WShape *shape)
{
  vector<WVertex*>	fvertices;
  vector<Vec3r>		vectors;
  vector<WFace*>	& faces = shape->GetFaceList();
  
  for (vector<WFace*>::const_iterator f = faces.begin(); f != faces.end(); f++) 
    {
      (*f)->RetrieveVertexList(fvertices);
      
      for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); wv++)
	vectors.push_back(Vec3r((*wv)->GetVertex()));
      
      // occluder will be deleted by the grid
      Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
      occluder->setId(_polygon_id++);
      occluder->userdata = (void*)(*f);
      _grid->insertOccluder(occluder);
      vectors.clear();
      fvertices.clear();
    }
  //  faces.clear();
}
Пример #7
0
void ThirdPersonCamera::UpdateViewMatrix(real dt)
{
	m_orientation.ToMatrix(m_viewMatrix.m_matrix);

    m_xAxis = Vec3r(m_viewMatrix.Access(0,0), m_viewMatrix.Access(1,0), m_viewMatrix.Access(2,0));
    m_yAxis = Vec3r(m_viewMatrix.Access(0,1), m_viewMatrix.Access(1,1), m_viewMatrix.Access(2,1));
    m_zAxis = Vec3r(m_viewMatrix.Access(0,2), m_viewMatrix.Access(1,2), m_viewMatrix.Access(2,2));

    // Calculate the new camera position. The 'idealPosition' is where the
    // camera should be position. The camera should be positioned directly
    // behind the target at the required offset distance. What we're doing here
    // is rather than have the camera immediately snap to the 'idealPosition'
    // we slowly move the camera towards the 'idealPosition' using a spring
    // system.
    //
    // References:
    //   Stone, Jonathan, "Third-Person Camera Navigation," Game Programming
    //     Gems 4, Andrew Kirmse, Editor, Charles River Media, Inc., 2004.

    //Vec3r idealPosition = m_target + m_zAxis * m_offsetDistance;
	Vec3r idealPosition = m_target + m_targetZAxis * m_offsetDistance;
    Vec3r displacement = m_eye - idealPosition;
    Vec3r springAcceleration = (displacement * -m_springConstant) - 
        (m_velocity * m_dampingConstant);

    m_velocity += springAcceleration * dt;
    m_eye += m_velocity * dt;

    // The view matrix is always relative to the camera's current position
    // 'm_eye'. Since a spring system is being used here 'm_eye' will be
    // relative to 'idealPosition'. When the camera is no longer being
    // moved 'm_eye' will become the same as 'idealPosition'. The local
    // x, y, and z axes that were extracted from the camera's orientation
    // 'm_orienation' is correct for the 'idealPosition' only. We need
    // to recompute these axes so that they're relative to 'm_eye'. Once
    // that's done we can use those axes to reconstruct the view matrix.

    m_zAxis = m_eye - m_target;
    m_zAxis.Normalise();

    m_xAxis = Vec3r::CrossProduct(m_targetYAxis, m_zAxis);
    m_xAxis.Normalise();

    m_yAxis = Vec3r::CrossProduct(m_zAxis, m_xAxis);
    m_yAxis.Normalise();

    m_viewMatrix.SetToIdentity();

    m_viewMatrix.Access(0,0) = m_xAxis.X;
    m_viewMatrix.Access(1,0) = m_xAxis.Y;
    m_viewMatrix.Access(2,0) = m_xAxis.Z;
	m_viewMatrix.Access(3,0) = -Vec3r::DotProduct(m_xAxis, m_eye);
				
    m_viewMatrix.Access(0,1) = m_yAxis.X;
    m_viewMatrix.Access(1,1) = m_yAxis.Y;
    m_viewMatrix.Access(2,1) = m_yAxis.Z;
	m_viewMatrix.Access(3,1) = -Vec3r::DotProduct(m_yAxis, m_eye);
				
    m_viewMatrix.Access(0,2) = m_zAxis.X;
    m_viewMatrix.Access(1,2) = m_zAxis.Y;
    m_viewMatrix.Access(2,2) = m_zAxis.Z;   
    m_viewMatrix.Access(3,2) = -Vec3r::DotProduct(m_zAxis, m_eye);

    m_viewDir = m_zAxis * -1;
}
Пример #8
0
SpikedFloor::SpikedFloor(Vec2r halfExtents, Vec2r worldPos)
{
	m_halfExtents = halfExtents;
	m_pos = Vec3r(worldPos.X, worldPos.Y, -1);
}
Пример #9
0
void PSStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
{
    if (_polylineOutput)
    {
        Stroke * stroke = iStrokeRep->getStroke();

        _ofstream << "newpath" << endl;
        _ofstream << _polylineWidth << " setlinewidth\n";
        _ofstream << "1 setlinejoin\n";  // select round line joins.  default is miter, which creates protrustions at high-curvature areas

        bool first = true;

        for(Stroke::const_vertex_iterator v = stroke->vertices_begin(); v != stroke->vertices_end(); v++)
        {
            const StrokeVertex * vert = (*v);

            if (first)
            {
                const StrokeAttribute & attrib = vert->attribute();
                Vec3f color = attrib.getColorRGB();
                if (color[0] == 1 && color[1] == 1 && color[2] == 1)
                    color = Vec3r (0,0,0);
                _ofstream << (color)[0] << " " << (color)[1] << " " << (color)[2] << " setrgbcolor" <<endl;
            }

            _ofstream << (double) vert->x() << " " <<  (double) vert->y() ;
            if (first)
                _ofstream << " moveto\n";
            else
                _ofstream << " lineto\n";

            real z = vert->z();
            _ofstream << "%% "<< (double) z <<" depth\n";

            first = false;
        }

        _ofstream << "stroke" << endl;
        //      _ofstream << "closepath" << endl;
        //      _ofstream << "fill" << endl;
    }
    else
    {
        vector<Strip*>& strips = iStrokeRep->getStrips();
        for(vector<Strip*>::iterator s=strips.begin(); s!=strips.end(); ++s)
        {
            Strip::vertex_container& vertices = (*s)->vertices();

            // output all the odd points, then all the even points in reverse

            Vec3f color = vertices[0]->color();

            if (color == Vec3f(1,1,1))
                color = Vec3r (0,0,0);

            _ofstream << "newpath" << endl;
            _ofstream << (color)[0] << " " << (color)[1] << " " << (color)[2] << " setrgbcolor" <<endl;

            bool first = true;

            for(int i=0;i<vertices.size(); i+=2)
            {
                StrokeVertexRep * svRep = vertices[i];
                _ofstream << (double) svRep->point2d()[0] << " " << (double) svRep->point2d()[1];
                if (first)
                    _ofstream << " moveto\n";
                else
                    _ofstream << " lineto\n";
                first = false;

            }

            for(int i=vertices.size()-1;i>=0;i-=2)
            {
                StrokeVertexRep * svRep = vertices[i];
                _ofstream << (double) svRep->point2d()[0] << " " << (double) svRep->point2d()[1] << " lineto\n";
            }

            _ofstream << "closepath" << endl;
            _ofstream << "fill" << endl;
        }
    }
}
Пример #10
0
Vec3r WOEdge::getVec3r ()
{
	return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex());
}
Пример #11
0
Boundary::Boundary()
{
    psi=0.0;
    x=Vec3r(0.0);
    v=Vec3r(0.0);
}
Пример #12
0
void Controller::ComputeViewMap()
{
	if (!_ListOfModels.size())
		return;

	if (NULL != _ViewMap) {
		delete _ViewMap;
		_ViewMap = NULL;
	}

	_pView->DetachDebug();
	if (NULL != _DebugNode) {
		int ref = _DebugNode->destroy();
		if (0 == ref)
			_DebugNode->addRef();
	}

	_pView->DetachSilhouette();
	if (NULL != _SilhouetteNode) {
		int ref = _SilhouetteNode->destroy();
		if (0 == ref)
			delete _SilhouetteNode;
	}

#if 0
	if (NULL != _ProjectedSilhouette) {
		int ref = _ProjectedSilhouette->destroy();
		if (0 == ref)
			delete _ProjectedSilhouette;
	}

	if (NULL != _VisibleProjectedSilhouette) {
		int ref = _VisibleProjectedSilhouette->destroy();
		if (0 == ref) {
			delete _VisibleProjectedSilhouette;
			_VisibleProjectedSilhouette = NULL;
		}
	}
#endif

	// retrieve the 3D viewpoint and transformations information
	//----------------------------------------------------------
	// Save the viewpoint context at the view level in order 
	// to be able to restore it later:

	// Restore the context of view:
	// we need to perform all these operations while the 
	// 3D context is on.
	Vec3r vp(freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]);

#if 0
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "mv" << endl;
	}
#endif
	real mv[4][4];
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			mv[i][j] = freestyle_mv[i][j];
#if 0
			if (G.debug & G_DEBUG_FREESTYLE) {
				cout << mv[i][j] << " ";
			}
#endif
		}
#if 0
		if (G.debug & G_DEBUG_FREESTYLE) {
			cout << endl;
		}
#endif
	}

#if 0
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\nproj" << endl;
	}
#endif
	real proj[4][4];
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			proj[i][j] = freestyle_proj[i][j];
#if 0
			if (G.debug & G_DEBUG_FREESTYLE) {
				cout << proj[i][j] << " ";
			}
#endif
		}
#if 0
		if (G.debug & G_DEBUG_FREESTYLE) {
			cout << endl;
		}
#endif
	}

	int viewport[4];
	for (int i = 0; i < 4; i++)
		viewport[i] = freestyle_viewport[i];

#if 0
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\nfocal:" << _pView->GetFocalLength() << endl << endl;
	}
#endif

	// Flag the WXEdge structure for silhouette edge detection:
	//----------------------------------------------------------

	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\n===  Detecting silhouette edges  ===" << endl;
	}
	_Chrono.start();

	edgeDetector.setViewpoint(Vec3r(vp));
	edgeDetector.enableOrthographicProjection(proj[3][3] != 0.0);
	edgeDetector.enableRidgesAndValleysFlag(_ComputeRidges);
	edgeDetector.enableSuggestiveContours(_ComputeSuggestive);
	edgeDetector.enableMaterialBoundaries(_ComputeMaterialBoundaries);
	edgeDetector.enableFaceSmoothness(_EnableFaceSmoothness);
	edgeDetector.setCreaseAngle(_creaseAngle);
	edgeDetector.setSphereRadius(_sphereRadius);
	edgeDetector.setSuggestiveContourKrDerivativeEpsilon(_suggestiveContourKrDerivativeEpsilon);
	edgeDetector.setRenderMonitor(_pRenderMonitor);
	edgeDetector.processShapes(*_winged_edge);

	real duration = _Chrono.stop();
	if (G.debug & G_DEBUG_FREESTYLE) {
		printf("Feature lines    : %lf\n", duration);
	}

	if (_pRenderMonitor->testBreak())
		return;

	// Builds the view map structure from the flagged WSEdge structure:
	//----------------------------------------------------------
	ViewMapBuilder vmBuilder;
	vmBuilder.setEnableQI(_EnableQI);
	vmBuilder.setViewpoint(Vec3r(vp));
	vmBuilder.setTransform(mv, proj, viewport, _pView->GetFocalLength(), _pView->GetAspect(), _pView->GetFovyRadian());
	vmBuilder.setFrustum(_pView->znear(), _pView->zfar());
	vmBuilder.setGrid(&_Grid);
	vmBuilder.setRenderMonitor(_pRenderMonitor);

	// Builds a tesselated form of the silhouette for display purpose:
	//---------------------------------------------------------------
	ViewMapTesselator3D sTesselator3d;
#if 0
	ViewMapTesselator2D sTesselator2d;
	sTesselator2d.setNature(_edgeTesselationNature);
#endif
	sTesselator3d.setNature(_edgeTesselationNature);

	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\n===  Building the view map  ===" << endl;
	}
	_Chrono.start();
	// Build View Map
	_ViewMap = vmBuilder.BuildViewMap(*_winged_edge, _VisibilityAlgo, _EPSILON, _Scene3dBBox, _SceneNumFaces);
	_ViewMap->setScene3dBBox(_Scene3dBBox);

	if (G.debug & G_DEBUG_FREESTYLE) {
		printf("ViewMap edge count : %i\n", _ViewMap->viewedges_size());
	}

	// Tesselate the 3D edges:
	_SilhouetteNode = sTesselator3d.Tesselate(_ViewMap);
	_SilhouetteNode->addRef();

	// Tesselate 2D edges
#if 0
	_ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap);
	_ProjectedSilhouette->addRef();
#endif

	duration = _Chrono.stop();
	if (G.debug & G_DEBUG_FREESTYLE) {
		printf("ViewMap building : %lf\n", duration);
	}

	_pView->AddSilhouette(_SilhouetteNode);
#if 0
	_pView->AddSilhouette(_WRoot);
	_pView->Add2DSilhouette(_ProjectedSilhouette);
	_pView->Add2DVisibleSilhouette(_VisibleProjectedSilhouette);
#endif
	_pView->AddDebug(_DebugNode);

	// Draw the steerable density map:
	//--------------------------------
	if (_ComputeSteerableViewMap) {
		ComputeSteerableViewMap();
	}
	// Reset Style modules modification flags
	resetModified(true);

	DeleteWingedEdge();
}
Пример #13
0
			SolidFixture()
			{
				sim = createSimulator();
				sim->setGravity( Vec3r( 0, -9.81, 0 ) );
				s = sim->createSolid();
			}
Пример #14
0
  /* splits an edge into several edges. 
   *  The edge's vertices are passed rather than 
   *  the edge itself. This way, all feature edges (SILHOUETTE,
   *  CREASE, BORDER) are splitted in the same time.
   *  The processed edges are flagged as done (using the userdata
   *  flag).One single new vertex is created whereas 
   *  several splitted edges might created for the different 
   *  kinds of edges. These new elements are added to the lists
   *  maintained by the shape.
   *  new chains are also created.
   *    ioA
   *      The first vertex for the edge that gets splitted
   *    ioB
   *      The second vertex for the edge that gets splitted
   *    iParameters
   *      A vector containing 2D real vectors indicating the parameters
   *      giving the intersections coordinates in 3D and in 2D.
   *      These intersections points must be sorted from B to A.
   *      Each parameter defines the intersection point I as I=A+T*AB.
   *      T<0 and T>1 are then incorrect insofar as they give intersections
   *      points that lie outside the segment.
   *    ioNewEdges
   *      The edges that are newly created (the initial edges are not 
   *      included) are added to this list.
   */
void SShape::SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges)
    {
    
    SVertex *ioA = fe->vertexA();
    SVertex *ioB = fe->vertexB();
    Vec3r A = ioA->point3D();
    Vec3r B = ioB->point3D();
    Vec3r a = ioA->point2D();
    Vec3r b = ioB->point2D();
    SVertex *svA, *svB;

    Vec3r newpoint3d,newpoint2d;
    vector<SVertex*> intersections;
    real t,T;
    for(vector<Vec2r>::const_iterator p=iParameters.begin(),pend=iParameters.end();
    p!=pend;
    p++)
    {
      T=(*p)[0];
      t=(*p)[1];

      if((t < 0) || (t > 1))
        cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl;
    
      // compute the 3D and 2D coordinates for the intersections points:
      newpoint3d = Vec3r(A + T*(B-A));
      newpoint2d = Vec3r(a + t*(b-a));

      // create new SVertex:
      // (we keep B's id)
      SVertex* newVertex = new SVertex(newpoint3d, ioB->getId());
      newVertex->SetPoint2D(newpoint2d);
      
      // Add this vertex to the intersections list:
      intersections.push_back(newVertex);

      // Add this vertex to this sshape:
      AddNewVertex(newVertex);
    }
    
    for(vector<SVertex*>::iterator sv=intersections.begin(),svend=intersections.end();
    sv!=svend;
    sv++)
    {
      svA = fe->vertexA();
      svB = fe->vertexB();
        
      // We split edge AB into AA' and A'B. A' and A'B are created.
      // AB becomes (address speaking) AA'. B is updated.
      //--------------------------------------------------
      // The edge AB becomes edge AA'.
      (fe)->SetVertexB((*sv));
      // a new edge, A'B is created.
      FEdge *newEdge;
      if (fe->getNature() & Nature::ALL_INTERSECTION)
	{
	  newEdge = new FEdgeIntersection((*sv), svB);
	  FEdgeIntersection * se = dynamic_cast<FEdgeIntersection*>(newEdge);
	  FEdgeIntersection * fes = dynamic_cast<FEdgeIntersection*>(fe);
	  se->SetMaterialIndex(fes->materialIndex());
	  se->SetFaces(fes->getFace1(), fes->getFace2());


#ifdef DEBUG_INTERSECTION
	  void debugFES(FEdgeIntersection * newEdge);
	  
	  debugFES(se);
	  debugFES(fes);
#endif



	}
      else
      if(fe->isSmooth()){
        newEdge = new FEdgeSmooth((*sv), svB);
        FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge);
        FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
        se->SetMaterialIndex(fes->materialIndex());
      }else{
        newEdge = new FEdgeSharp((*sv), svB);
        FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge);
        FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(fe);
        se->SetaMaterialIndex(fes->aMaterialIndex());
        se->SetbMaterialIndex(fes->bMaterialIndex());
	se->SetEdge(fes->edge());
      }
        
      newEdge->SetNature((fe)->getNature());
      

      // to build a new chain:
      AddChain(newEdge);
      // add the new edge to the sshape edges list.
      AddEdge(newEdge);
      // add new edge to the list of new edges passed as argument:
      ioNewEdges.push_back(newEdge);

      // update edge A'B for the next pointing edge
      newEdge->SetNextEdge((fe)->nextEdge());
      fe->nextEdge()->SetPreviousEdge(newEdge);
      Id id(fe->getId().getFirst(), fe->getId().getSecond()+1);
      newEdge->SetId(fe->getId());
      fe->SetId(id);

      // update edge AA' for the next pointing edge
      //ioEdge->SetNextEdge(newEdge);
      (fe)->SetNextEdge(NULL);

      // update vertex pointing edges list:
      // -- vertex B --
      svB->Replace((fe), newEdge);
      // -- vertex A' --
      (*sv)->AddFEdge((fe));
      (*sv)->AddFEdge(newEdge);
    }
          
    }
namespace Freestyle {

Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0);
real SilhouetteGeomEngine::_translation[3] = {0, 0, 0};
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {
	{1, 0, 0, 0},
	{0, 1, 0, 0},
	{0, 0, 1, 0},
	{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
	{1, 0, 0, 0},
	{0, 1, 0, 0},
	{0, 0, 1, 0},
	{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_transform[4][4] = {
	{1, 0, 0, 0},
	{0, 1, 0, 0},
	{0, 0, 1, 0},
	{0, 0, 0, 1}
};
int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
real SilhouetteGeomEngine::_Focal = 0.0;

real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
	{1, 0, 0, 0},
	{0, 1, 0, 0},
	{0, 0, 1, 0},
	{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
	{1, 0, 0, 0},
	{0, 1, 0, 0},
	{0, 0, 1, 0},
	{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_znear = 0.0;
real SilhouetteGeomEngine::_zfar = 100.0;
bool SilhouetteGeomEngine::_isOrthographicProjection = false;

SilhouetteGeomEngine *SilhouetteGeomEngine::_pInstance = NULL;

void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
                                        const int iViewport[4], real iFocal)
{
	unsigned int i, j;
	_translation[0] = iModelViewMatrix[3][0];
	_translation[1] = iModelViewMatrix[3][1];
	_translation[2] = iModelViewMatrix[3][2];

	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			_modelViewMatrix[i][j] = iModelViewMatrix[j][i];
			_glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
		}
	}

	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			_projectionMatrix[i][j] = iProjectionMatrix[j][i];
			_glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
		}
	}

	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			_transform[i][j] = 0;
			for (unsigned int k = 0; k < 4; k++)
				_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
		}
	}

	for (i = 0; i < 4; i++) {
		_viewport[i] = iViewport[i];
	}
	_Focal = iFocal;

	_isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0);
}

void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
{
	_znear = iZNear;
	_zfar = iZFar;
}

void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
{
	memcpy(viewport, _viewport, 4 * sizeof(int));
}

void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
{
	Vec3r newPoint;
	vector<SVertex*>::iterator sv, svend;
	for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
		GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
		(*sv)->setPoint2D(newPoint);
	}
}

void SilhouetteGeomEngine::ProjectSilhouette(SVertex *ioVertex)
{
	Vec3r newPoint;
	GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
	ioVertex->setPoint2D(newPoint);
}

real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
{
	if (_isOrthographicProjection)
		return t;

	// we need to compute for each parameter t the corresponding parameter T which gives the intersection in 3D.
	real T;

	// suffix w for world, c for camera, r for retina, i for image
	Vec3r Aw = (fe)->vertexA()->point3D();
	Vec3r Bw = (fe)->vertexB()->point3D();
	Vec3r Ac, Bc;
	GeomUtils::fromWorldToCamera(Aw, Ac, _modelViewMatrix);
	GeomUtils::fromWorldToCamera(Bw, Bc, _modelViewMatrix);
	Vec3r ABc = Bc - Ac;
#if 0
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "Ac " << Ac << endl;
		cout << "Bc " << Bc << endl;
		cout << "ABc " << ABc << endl;
	}
#endif
	Vec3r Ai = (fe)->vertexA()->point2D();
	Vec3r Bi = (fe)->vertexB()->point2D();
	Vec3r Ii = Ai + t * (Bi - Ai); // the intersection point in the 2D image space
	Vec3r Ir, Ic;
	GeomUtils::fromImageToRetina(Ii, Ir, _viewport);

	real alpha, beta, denom;
	real m11 = _projectionMatrix[0][0];
	real m13 = _projectionMatrix[0][2];
	real m22 = _projectionMatrix[1][1];
	real m23 = _projectionMatrix[1][2];

	if (fabs(ABc[0]) > 1.0e-6) {
		alpha = ABc[2] / ABc[0];
		beta = Ac[2] - alpha * Ac[0];
		denom = alpha * (Ir[0] + m13) + m11;
		if (fabs(denom) < 1.0e-6)
			goto iter;
		Ic[0] = -beta * (Ir[0] + m13) / denom;
#if 0
		Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
		Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
#endif
		T = (Ic[0] - Ac[0]) / ABc[0];

	}
	else if (fabs(ABc[1]) > 1.0e-6) {
		alpha = ABc[2] / ABc[1];
		beta = Ac[2] - alpha * Ac[1];
		denom = alpha * (Ir[1] + m23) + m22;
		if (fabs(denom) < 1.0e-6)
			goto iter;
		Ic[1] = -beta * (Ir[1] + m23) / denom;
#if 0
		Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
		Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
#endif
		T = (Ic[1] - Ac[1]) / ABc[1];
	}
	else {
iter:
		bool x_coords, less_than;
		if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
			x_coords = true;
			less_than = Ai[0] < Bi[0];
		}
		else {
			x_coords = false;
			less_than = Ai[1] < Bi[1];
		}
		Vec3r Pc, Pr, Pi;
		real T_sta = 0.0;
		real T_end = 1.0;
		real delta_x, delta_y, dist, dist_threshold = 1.0e-6;
		int i, max_iters = 100;
		for (i = 0; i < max_iters; i++) {
			T = T_sta + 0.5 * (T_end - T_sta);
			Pc = Ac + T * ABc;
			GeomUtils::fromCameraToRetina(Pc, Pr, _projectionMatrix);
			GeomUtils::fromRetinaToImage(Pr, Pi, _viewport);
			delta_x = Ii[0] - Pi[0];
			delta_y = Ii[1] - Pi[1];
			dist = sqrt(delta_x * delta_x + delta_y * delta_y);
			if (dist < dist_threshold)
				break;
			if (x_coords) {
				if (less_than) {
					if (Pi[0] < Ii[0])
						T_sta = T;
					else
						T_end = T;
				}
				else {
					if (Pi[0] > Ii[0])
						T_sta = T;
					else
						T_end = T;
				}
			}
			else {
				if (less_than) {
					if (Pi[1] < Ii[1])
						T_sta = T;
					else
						T_end = T;
				}
				else {
					if (Pi[1] > Ii[1])
						T_sta = T;
					else
						T_end = T;
				}
			}
		}
#if 0
		if (G.debug & G_DEBUG_FREESTYLE) {
			cout << "SilhouetteGeomEngine::ImageToWorldParameter(): #iters = " << i << ", dist = " << dist << "\n";
		}
#endif
		if (i == max_iters && G.debug & G_DEBUG_FREESTYLE) {
			cout << "SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = " << dist << ")\n";
		}
	}

	return T;
}

Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
{
	Vec3r newPoint;
	GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
	return newPoint;
}

Vec3r SilhouetteGeomEngine::CameraToImage(const Vec3r& M)
{
	Vec3r newPoint, p;
	GeomUtils::fromCameraToRetina(M, p, _projectionMatrix);
	GeomUtils::fromRetinaToImage(p, newPoint, _viewport);
	return newPoint;
}

} /* namespace Freestyle */
Пример #16
0
void FEdgeXDetector::computeCurvatures(WXVertex *vertex)
{
	// TODO: for some reason, the 'vertex' may have no associated edges
	// (i.e., WVertex::_EdgeList is empty), which causes a crash due to
	// a subsequent call of WVertex::_EdgeList.front().
	if (vertex->GetEdges().empty()) {
		if (G.debug & G_DEBUG_FREESTYLE) {
			printf("Warning: WVertex %d has no associated edges.\n", vertex->GetId());
		}
		return;
	}

	// CURVATURE LAYER
	// store all the curvature datas for each vertex

	//soc unused - real K1, K2
	real cos2theta, sin2theta;
	Vec3r e1, n, v;
	// one vertex curvature info :
	CurvatureInfo *C;
	float radius = _sphereRadius * _meanEdgeSize;

	// view independent stuff
	if (_computeViewIndependent) {
		C = new CurvatureInfo();
		vertex->setCurvatures(C);
		OGF::NormalCycle ncycle;
		ncycle.begin();
		if (radius > 0) {
			OGF::compute_curvature_tensor(vertex, radius, ncycle);
		}
		else {
			OGF::compute_curvature_tensor_one_ring(vertex, ncycle);
		}
		ncycle.end();
		C->K1 = ncycle.kmin();
		C->K2 = ncycle.kmax();
		C->e1 = ncycle.Kmax(); //ncycle.kmin() * ncycle.Kmax();
		C->e2 = ncycle.Kmin(); //ncycle.kmax() * ncycle.Kmin();

		real absK1 = fabs(C->K1);
		_meanK1 += absK1;
		if (absK1 > _maxK1)
			_maxK1 = absK1;
		if (absK1 < _minK1)
			_minK1 = absK1;
	}
	// view dependant
	C = vertex->curvatures();
	if (C == 0)
		return;

	// compute radial curvature :
	n = C->e1 ^ C->e2;
	if (_orthographicProjection) {
		v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z());
	}
	else {
		v = Vec3r(_Viewpoint - vertex->GetVertex());
	}
	C->er = v - (v * n) * n;
	C->er.normalize();
	e1 = C->e1;
	e1.normalize();
	cos2theta = C->er * e1;
	cos2theta *= cos2theta;
	sin2theta = 1 - cos2theta;
	C->Kr = C->K1 * cos2theta + C->K2 * sin2theta;
	real absKr = fabs(C->Kr);
	_meanKr += absKr;
	if (absKr > _maxKr)
		_maxKr = absKr;
	if (absKr < _minKr)
		_minKr = absKr;

	++_nPoints;
}
Пример #17
0
FlatFloor::FlatFloor(UInt segmentNum, Vec2r worldPos) : m_segmentNum(segmentNum)
{
	m_pos = Vec3r(worldPos.X, worldPos.Y, -1);
}
Пример #18
0
/*! gts_vertex_principal_directions:
 *  @v: a #WVertex.
 *  @s: a #GtsSurface.
 *  @Kh: mean curvature normal (a #Vec3r).
 *  @Kg: Gaussian curvature (a real).
 *  @e1: first principal curvature direction (direction of largest curvature).
 *  @e2: second principal curvature direction.
 *
 *  Computes the principal curvature directions at a point given @Kh and @Kg, the mean curvature normal and
 *  Gaussian curvatures at that point, computed with gts_vertex_mean_curvature_normal() and
 *  gts_vertex_gaussian_curvature(), respectively.
 *
 *  Note that this computation is very approximate and tends to be unstable. Smoothing of the surface or the principal
 *  directions may be necessary to achieve reasonable results.
 */
void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2)
{
	Vec3r N;
	real normKh;

	Vec3r basis1, basis2, d, eig;
	real ve2, vdotN;
	real aterm_da, bterm_da, cterm_da, const_da;
	real aterm_db, bterm_db, cterm_db, const_db;
	real a, b, c;
	real K1, K2;
	real *weights, *kappas, *d1s, *d2s;
	int edge_count;
	real err_e1, err_e2;
	int e;
	WVertex::incoming_edge_iterator itE;

	/* compute unit normal */
	normKh = Kh.norm();

	if (normKh > 0.0) {
		Kh.normalize();
	}
	else {
		/* This vertex is a point of zero mean curvature (flat or saddle point). Compute a normal by averaging
		 * the adjacent triangles
		 */
		N[0] = N[1] = N[2] = 0.0;

		for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
			N = Vec3r(N + (*itE)->GetaFace()->GetNormal());
		real normN = N.norm();
		if (normN <= 0.0)
			return;
		N.normalize();
	}

	/* construct a basis from N: */
	/* set basis1 to any component not the largest of N */
	basis1[0] =  basis1[1] =  basis1[2] = 0.0;
	if (fabs (N[0]) > fabs (N[1]))
		basis1[1] = 1.0;
	else
		basis1[0] = 1.0;

	/* make basis2 orthogonal to N */
	basis2 = (N ^ basis1);
	basis2.normalize();

	/* make basis1 orthogonal to N and basis2 */
	basis1 = (N ^ basis2);
	basis1.normalize();

	aterm_da = bterm_da = cterm_da = const_da = 0.0;
	aterm_db = bterm_db = cterm_db = const_db = 0.0;
	int nb_edges = v->GetEdges().size();

	weights = (real *)malloc(sizeof(real) * nb_edges);
	kappas = (real *)malloc(sizeof(real) * nb_edges);
	d1s = (real *)malloc(sizeof(real) * nb_edges);
	d2s = (real *)malloc(sizeof(real) * nb_edges);
	edge_count = 0;

	for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
		WOEdge *e;
		WFace *f1, *f2;
		real weight, kappa, d1, d2;
		Vec3r vec_edge;
		if (!*itE)
			continue;
		e = *itE;

		/* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be true. */
		//g_assert(gts_edge_face_number (e, s) == 2);

		/* identify the two triangles bordering e in s */
		f1 = e->GetaFace();
		f2 = e->GetbFace();

		/* We are solving for the values of the curvature tensor
		 *     B = [ a b ; b c ].
		 *  The computations here are from section 5 of [Meyer et al 2002].
		 *
		 *  The first step is to calculate the linear equations governing the values of (a,b,c). These can be computed
		 *  by setting the derivatives of the error E to zero (section 5.3).
		 *
		 *  Since a + c = norm(Kh), we only compute the linear equations for dE/da and dE/db. (NB: [Meyer et al 2002]
		 *  has the equation a + b = norm(Kh), but I'm almost positive this is incorrect).
		 *
		 *  Note that the w_ij (defined in section 5.2) are all scaled by (1/8*A_mixed). We drop this uniform scale
		 *  factor because the solution of the linear equations doesn't rely on it.
		 *
		 *  The terms of the linear equations are xterm_dy with x in {a,b,c} and y in {a,b}. There are also const_dy
		 *  terms that are the constant factors in the equations.
		 */

		/* find the vector from v along edge e */
		vec_edge = Vec3r(-1 * e->GetVec());

		ve2 = vec_edge.squareNorm();
		vdotN = vec_edge * N;

		/* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */
		kappa = 2.0 * vdotN / ve2;

		/* section 5.2 */

		/* I don't like performing a minimization where some of the weights can be negative (as can be the case
		 *  if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness. */
		weight = 0.0;
		if (!triangle_obtuse(v, f1)) {
			weight += ve2 * cotan(f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
		}
		else {
			if (angle_obtuse(v, f1)) {
				weight += ve2 * f1->getArea() / 4.0;
			}
			else {
				weight += ve2 * f1->getArea() / 8.0;
			}
		}

		if (!triangle_obtuse(v, f2)) {
			weight += ve2 * cotan (f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
		}
		else {
			if (angle_obtuse(v, f2)) {
				weight += ve2 * f1->getArea() / 4.0;
			}
			else {
				weight += ve2 * f1->getArea() / 8.0;
			}
		}

		/* projection of edge perpendicular to N (section 5.3) */
		d[0] = vec_edge[0] - vdotN * N[0];
		d[1] = vec_edge[1] - vdotN * N[1];
		d[2] = vec_edge[2] - vdotN * N[2];
		d.normalize();

		/* not explicit in the paper, but necessary. Move d to 2D basis. */
		d1 = d * basis1;
		d2 = d * basis2;

		/* store off the curvature, direction of edge, and weights for later use */
		weights[edge_count] = weight;
		kappas[edge_count] = kappa;
		d1s[edge_count] = d1;
		d2s[edge_count] = d2;
		edge_count++;

		/* Finally, update the linear equations */
		aterm_da += weight * d1 * d1 * d1 * d1;
		bterm_da += weight * d1 * d1 * 2 * d1 * d2;
		cterm_da += weight * d1 * d1 * d2 * d2;
		const_da += weight * d1 * d1 * (-kappa);

		aterm_db += weight * d1 * d2 * d1 * d1;
		bterm_db += weight * d1 * d2 * 2 * d1 * d2;
		cterm_db += weight * d1 * d2 * d2 * d2;
		const_db += weight * d1 * d2 * (-kappa);
	}

	/* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
	aterm_da -= cterm_da;
	const_da += cterm_da * normKh;

	aterm_db -= cterm_db;
	const_db += cterm_db * normKh;

	/* check for solvability of the linear system */
	if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && ((const_da != 0.0) || (const_db != 0.0))) {
		linsolve(aterm_da, bterm_da, -const_da, aterm_db, bterm_db, -const_db, &a, &b);

		c = normKh - a;

		eigenvector(a, b, c, eig);
	}
	else {
		/* region of v is planar */
		eig[0] = 1.0;
		eig[1] = 0.0;
	}

	/* Although the eigenvectors of B are good estimates of the principal directions, it seems that which one is
	 * attached to which curvature direction is a bit arbitrary. This may be a bug in my implementation, or just
	 * a side-effect of the inaccuracy of B due to the discrete nature of the sampling.
	 *
	 * To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors by comparing
	 * the curvature estimates computed above and the curvatures calculated from the discrete differential operators.
	 */

	gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2);

	err_e1 = err_e2 = 0.0;
	/* loop through the values previously saved */
	for (e = 0; e < edge_count; e++) {
		real weight, kappa, d1, d2;
		real temp1, temp2;
		real delta;

		weight = weights[e];
		kappa = kappas[e];
		d1 = d1s[e];
		d2 = d2s[e];

		temp1 = fabs (eig[0] * d1 + eig[1] * d2);
		temp1 = temp1 * temp1;
		temp2 = fabs (eig[1] * d1 - eig[0] * d2);
		temp2 = temp2 * temp2;

		/* err_e1 is for K1 associated with e1 */
		delta = K1 * temp1 + K2 * temp2 - kappa;
		err_e1 += weight * delta * delta;

		/* err_e2 is for K1 associated with e2 */
		delta = K2 * temp1 + K1 * temp2 - kappa;
		err_e2 += weight * delta * delta;
	}
	free (weights);
	free (kappas);
	free (d1s);
	free (d2s);

	/* rotate eig by a right angle if that would decrease the error */
	if (err_e2 < err_e1) {
		real temp = eig[0];

		eig[0] = eig[1];
		eig[1] = -temp;
	}

	e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0];
	e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1];
	e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2];
	e1.normalize();

	/* make N,e1,e2 a right handed coordinate sytem */
	e2 =  N ^ e1;
	e2.normalize();
}
Пример #19
0
Key::Key(Vec2r halfExtents, Vec2r worldPos): m_pDoor(nullptr)
{
	m_halfExtents = halfExtents;
	m_pos = Vec3r(worldPos.X, worldPos.Y, -1);
}
void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
                                           const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
                                           const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
                                           const unsigned *tindices, const unsigned nvertices)
{
	unsigned nDoneVertices = 2; // number of vertices already treated
	unsigned nTriangle = 0;     // number of the triangle currently being treated
	//int nVertex = 0;            // vertex number

	WShape *currentShape = _current_wshape; // the current shape being built
	vector<WVertex *> triangleVertices;
	vector<Vec3r> triangleNormals;
	vector<Vec2r> triangleTexCoords;
	vector<bool> triangleFaceEdgeMarks;

	while (nDoneVertices < nvertices) {
		//clear the vertices list:
		triangleVertices.clear();
		//Then rebuild it:
		if (0 == nTriangle % 2) { // if nTriangle is even
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);

			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
			                                normals[nindices[nTriangle] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
			                                normals[nindices[nTriangle + 1] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
			                                normals[nindices[nTriangle + 2] + 2]));

			if (texCoords) {
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
				                                  texCoords[tindices[nTriangle + 1] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
				                                  texCoords[tindices[nTriangle + 2] + 1]));
			}
		}
		else {                 // if nTriangle is odd
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);

			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
			                                normals[nindices[nTriangle] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
			                                normals[nindices[nTriangle + 2] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
			                                normals[nindices[nTriangle + 1] + 2]));

			if (texCoords) {
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
				                                  texCoords[tindices[nTriangle + 2] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
				                                  texCoords[tindices[nTriangle + 1] + 1]));
			}
		}
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
		if (mindices) {
			currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
			                       mindices[nTriangle / 3]);
		}
		else {
			currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
		}
		nDoneVertices++; // with a strip, each triangle is one vertex more
		nTriangle++;
	}
}
Пример #21
0
Vec3r BoxGrid::Transform::operator()(const Vec3r& point) const
{
	return Vec3r(point[0], point[1], -point[2]);
}
Пример #22
0
void Grid::insertOccluder(Polygon3r* occluder) {
  const vector<Vec3r> vertices = occluder->getVertices();
  if (vertices.size() == 0)
    return;

  // add this occluder to the grid's occluders list
  addOccluder(occluder);

  // find the bbox associated to this polygon
  Vec3r min, max;
  occluder->getBBox(min, max);

  // Retrieve the cell x, y, z cordinates associated with these min and max
  Vec3u imax, imin;
  getCellCoordinates(max, imax);
  getCellCoordinates(min, imin);
  
  // We are now going to fill in the cells overlapping with the
  // polygon bbox.
  // If the polygon is a triangle (most of cases), we also
  // check for each of these cells if it is overlapping with
  // the triangle in order to only fill in the ones really overlapping
  // the triangle.

  unsigned i, x, y, z;
  vector<Vec3r>::const_iterator it;
  Vec3u coord;

  if (vertices.size() == 3) { // Triangle case
    Vec3r triverts[3];
    i = 0;
    for(it = vertices.begin();
	it != vertices.end();
	it++) {
      triverts[i] = Vec3r(*it);
      i++;
    }

    Vec3r boxmin, boxmax;

    for (z = imin[2]; z <= imax[2]; z++)
      for (y = imin[1]; y <= imax[1]; y++)
	for (x = imin[0]; x <= imax[0]; x++) {
	  coord[0] = x;
	  coord[1] = y;
	  coord[2] = z;
	  // We retrieve the box coordinates of the current cell
	  getCellBox(coord, boxmin, boxmax);
	  // We check whether the triangle and the box ovewrlap:
	  Vec3r boxcenter((boxmin + boxmax) / 2.0);
	  Vec3r boxhalfsize(_cell_size / 2.0);
	  if (GeomUtils::overlapTriangleBox(boxcenter, boxhalfsize, triverts)) {
	    // We must then create the Cell and add it to the cells list
	    // if it does not exist yet.
	    // We must then add the occluder to the occluders list of this cell.
	    Cell* cell = getCell(coord);
	    if (!cell) {
	      cell = new Cell(boxmin);
	      fillCell(coord, *cell);
	    }
	    cell->addOccluder(occluder);
	  }
	}
  }
  else { // The polygon is not a triangle, we add all the cells overlapping the polygon bbox.
    for (z = imin[2]; z <= imax[2]; z++)
      for (y = imin[1]; y <= imax[1]; y++)
	for (x = imin[0]; x <= imax[0]; x++) {
	  coord[0] = x;
	  coord[1] = y;
	  coord[2] = z;
	  Cell* cell = getCell(coord);
	  if (!cell) {
	    Vec3r orig;
	    getCellOrigin(coord, orig);
	    cell = new Cell(orig);
	    fillCell(coord, *cell);
	  }
	  cell->addOccluder(occluder);
	}
  }
}