Пример #1
0
bool RArcData::moveReferencePoint(const RVector& referencePoint, const RVector& targetPoint) {
    bool ret = false;
    if (referencePoint.equalsFuzzy(center)) {
        center = targetPoint;
        ret = true;
    } else if (referencePoint.equalsFuzzy(getStartPoint())) {
        moveStartPoint(targetPoint);
        ret = true;
    } else if (referencePoint.equalsFuzzy(getEndPoint())) {
        moveEndPoint(targetPoint);
        ret = true;
    }
    else if (referencePoint.equalsFuzzy(center + RVector(radius, 0)) ||
             referencePoint.equalsFuzzy(center + RVector(0, radius)) ||
             referencePoint.equalsFuzzy(center - RVector(radius, 0)) ||
             referencePoint.equalsFuzzy(center - RVector(0, radius))) {
        radius = center.getDistanceTo(targetPoint);
        ret = true;
    }
    else if (referencePoint.equalsFuzzy(getMiddlePoint())) {
        moveMiddlePoint(targetPoint);
        ret = true;
    }
    return ret;
}
Пример #2
0
QList<RVector> RSpline::getMiddlePoints() const {
    QList<RVector> ret;

    ret.append(getMiddlePoint());

    return ret;
}
Пример #3
0
RS_Vector RS_Line::getNearestPointOnEntity(const RS_Vector& coord,
        bool onEntity, double* dist, RS_Entity** entity)const {

    if (entity!=NULL) {
        *entity = const_cast<RS_Line*>(this);
    }
//std::cout<<"RS_Line::getNearestPointOnEntity():"<<coord<<std::endl;
    RS_Vector direction = data.endpoint-data.startpoint;
    RS_Vector vpc=coord-data.startpoint;
    double a=direction.squared();
    if( a < RS_TOLERANCE*RS_TOLERANCE) {
        //line too short
        vpc=getMiddlePoint();
    }else{
        //find projection on line
        vpc = data.startpoint + direction*RS_Vector::dotP(vpc,direction)/a;
        if( !isHelpLayer() && onEntity &&
                ! vpc.isInWindowOrdered(minV,maxV) ){
//                !( vpc.x>= minV.x && vpc.x <= maxV.x && vpc.y>= minV.y && vpc.y<=maxV.y) ) {
            //projection point not within range, find the nearest endpoint
//            std::cout<<"not within window, returning endpoints\n";
            return getNearestEndpoint(coord,dist);
        }
    }

    if (dist!=NULL) {
        *dist = vpc.distanceTo(coord);
    }
    return vpc;
}
Пример #4
0
RS_Vector RS_Line::getNearestPointOnEntity(const RS_Vector& coord,
                                           bool onEntity, double* dist, RS_Entity** entity)const {

	if (entity) {
        *entity = const_cast<RS_Line*>(this);
    }
    RS_Vector direction = data.endpoint-data.startpoint;
    RS_Vector vpc=coord-data.startpoint;
    double a=direction.squared();
    if( a < RS_TOLERANCE2) {
        //line too short
        vpc=getMiddlePoint();
    }else{
        //find projection on line
        const double t=RS_Vector::dotP(vpc,direction)/a;
        if( !isConstruction() && onEntity &&
                ( t<=-RS_TOLERANCE || t>=1.+RS_TOLERANCE )
                ){
            //                !( vpc.x>= minV.x && vpc.x <= maxV.x && vpc.y>= minV.y && vpc.y<=maxV.y) ) {
            //projection point not within range, find the nearest endpoint
            //            std::cout<<"not within window, returning endpoints\n";
            return getNearestEndpoint(coord,dist);
        }
        vpc = data.startpoint + direction*t;
    }

	if (dist) {
        *dist = vpc.distanceTo(coord);
    }
    return vpc;
}
Пример #5
0
QList<RRefPoint> RArcData::getReferencePoints(RS::ProjectionRenderingHint hint) const {
    Q_UNUSED(hint)

    QList<RRefPoint> ret;
    ret.append(RRefPoint(center, RRefPoint::Center));
    ret.append(getStartPoint());
    ret.append(getEndPoint());
    ret.append(RRefPoint(getMiddlePoint(), RRefPoint::Secondary));

    QList<RRefPoint> p;
    p.append(RRefPoint(center + RVector(radius, 0), RRefPoint::Secondary));
    p.append(RRefPoint(center + RVector(0, radius), RRefPoint::Secondary));
    p.append(RRefPoint(center - RVector(radius, 0), RRefPoint::Secondary));
    p.append(RRefPoint(center - RVector(0, radius), RRefPoint::Secondary));

    for (int i=0; i<p.size(); i++) {
        if (RMath::isAngleBetween(center.getAngleTo(p[i]), startAngle, endAngle, reversed)) {
            ret.append(p[i]);
        }
    }

    return ret;
}
Пример #6
0
RS_Vector RS_Line::getNearestPointOnEntity(const RS_Vector& coord,
                                           bool onEntity,
                                           double* dist,
                                           RS_Entity** entity) const
{
    if (entity) {
        *entity = const_cast<RS_Line*>(this);
    }

    RS_Vector direction {data.endpoint - data.startpoint};
    RS_Vector vpc {coord - data.startpoint};
    double a {direction.squared()};

    if( a < RS_TOLERANCE2) {
        //line too short
        vpc = getMiddlePoint();
    }
    else {
        //find projection on line
        const double t {RS_Vector::dotP( vpc, direction) / a};
        if( !isConstruction()
            && onEntity
            && ( t <= -RS_TOLERANCE
                 || t >= 1. + RS_TOLERANCE ) ) {
            //projection point not within range, find the nearest endpoint
            return getNearestEndpoint( coord, dist);
        }

        vpc = data.startpoint + direction * t;
    }

    if (dist) {
        *dist = vpc.distanceTo( coord);
    }

    return vpc;
}
/*----------------------------------------------------------------------------------
Author: MaxAshton
function: createPoints
Description: create the initial points using 4 squares each set perpendiculars to each
		     other
----------------------------------------------------------------------------------*/
void IcoSphereGeometry::createPoints()
{
	// create 12 vertices of a icosahedron
	float ft = ( 1.0 + sqrt( 5.0 ) ) / 2.0;

	addVertex( new osg::Vec3f( -1.0f,  ft,  0.0f ) );
	addVertex( new osg::Vec3f( 1.0f,  ft, 0.0f ) );
	addVertex( new osg::Vec3f( -1.0f, -ft,  0.0f ) );
	addVertex( new osg::Vec3f( 1.0f, -ft,  0.0f ) );

	addVertex( new osg::Vec3f( 0.0f, -1.0f,  ft ) );
	addVertex( new osg::Vec3f( 0.0f,  1.0f,  ft ) );
	addVertex( new osg::Vec3f( 0.0f, -1.0f, -ft ) );
	addVertex( new osg::Vec3f( 0.0f,  1.0f, -ft ) );

	addVertex( new osg::Vec3f( ft,  0.0f, -1.0f ) );
	addVertex( new osg::Vec3f( ft,  0.0f,  1.0f ) );
	addVertex( new osg::Vec3f( -ft,  0.0f, -1.0f ) );
	addVertex( new osg::Vec3f( -ft,  0.0f,  1.0f ) );

	// 5 faces around point 0
	_pvTriangleIndexes->push_back( new osg::Vec3f( 0, 11, 5 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 0, 5, 1 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 0, 1, 7 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 0, 7, 10) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 0, 10, 11 ) );

	// 5 adjacent faces
	_pvTriangleIndexes->push_back( new osg::Vec3f( 1, 5, 9 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 5, 11, 4 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 11, 10, 2 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 10, 7, 6 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 7, 1, 8 ) );

	// 5 faces around point 3
	_pvTriangleIndexes->push_back( new osg::Vec3f( 3, 9, 4 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 3, 4, 2 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 3, 2, 6 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 3, 6, 8 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 3, 8, 9 ) );

	// 5 adjacent faces
	_pvTriangleIndexes->push_back( new osg::Vec3f( 4, 9, 5 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 2, 4, 11 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 6, 2, 10 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 8, 6, 7 ) );
	_pvTriangleIndexes->push_back( new osg::Vec3f( 9, 8, 1 ) );

	// refine triangles
	for ( unsigned int i = 0; i < _uiRecursionLevel; i++ )
	{
		std::vector<osg::Vec3f*>* pvNewFaces = new std::vector<osg::Vec3f*>();
	
		for( std::vector<osg::Vec3f*>::iterator i = _pvTriangleIndexes->begin(); i != _pvTriangleIndexes->end(); i++ )
		{
			// replace triangle by 4 triangles
			int a = getMiddlePoint( ( *i )->x(), ( *i )->y() );				
			int b = getMiddlePoint( ( *i )->y() , ( *i )->z() );
			int c = getMiddlePoint( ( *i )->z() , ( *i )->x() );

			pvNewFaces->push_back( new osg::Vec3f( ( *i )->x(), a, c ) );
			pvNewFaces->push_back( new osg::Vec3f( ( *i )->y(), b, a ) );
			pvNewFaces->push_back( new osg::Vec3f( ( *i )->z(), c, b ) );
			pvNewFaces->push_back( new osg::Vec3f( a, b, c ) );
		}

		_pvTriangleIndexes->empty();
		delete _pvTriangleIndexes;
		_pvTriangleIndexes = 0;
		_pvTriangleIndexes = pvNewFaces;
	}
}
Пример #8
0
void ege::icoSphere::create(etk::Hash<ememory::SharedPtr<ege::Material>>& _materials, etk::Hash<FaceIndexing>& _listFaces, std::vector<vec3>& _listVertex, std::vector<vec2>& _listUV,
                            const std::string& _materialName, float _size, int32_t _recursionLevel) {
	/*
	                                     5                                                  
	                                    o                                                   
	                                   /|                                                   
	                                  / |                                                   
	                                 /  |                                                   
	                                /   |                                                   
	                   11          /    |       9                                           
	      Z              o--------/...---------0   1                                        
	      |    y         |      4o o....|......|--o                                         
	      |   /          |       |. 0   |      | /                                          
	      |  /           |      .|      .      |/                                           
	      | /            |     . |      .      |                                            
	      |/             |    /  |      .     .|                                            
	      o-------x      |   /   |      .    / |                                            
	                     o--/....|........../--o                                            
	                   10  /     |     7o  /    8                                           
	                      /      .     .  /                                                 
	                     /       .    .  /                                                  
	                    o---------------o                                                   
	                   2         |  /    3                                                  
	                             | /                                                        
	                             |/                                                         
	                             o                                                          
	                            6                                                           
	*/
	// create 12 vertices of a icosahedron
	double size = 1.0;
	double ttt = (1.0 + sqrt(5.0)) / 2.0*size;
	EGE_ERROR("podition : " << ttt);
	_listVertex.push_back(vec3(-size,  ttt,  0.0).normalize()); // 0
	_listVertex.push_back(vec3( size,  ttt,  0.0).normalize()); // 1
	_listVertex.push_back(vec3(-size, -ttt,  0.0).normalize()); // 2
	_listVertex.push_back(vec3( size, -ttt,  0.0).normalize()); // 3

	_listVertex.push_back(vec3( 0.0, -1,  ttt).normalize()); // 4
	_listVertex.push_back(vec3( 0.0,  1,  ttt).normalize()); // 5
	_listVertex.push_back(vec3( 0.0, -1, -ttt).normalize()); // 6
	_listVertex.push_back(vec3( 0.0,  1, -ttt).normalize()); // 7

	_listVertex.push_back(vec3( ttt,  0.0, -size).normalize()); // 8
	_listVertex.push_back(vec3( ttt,  0.0,  size).normalize()); // 9
	_listVertex.push_back(vec3(-ttt,  0.0, -size).normalize()); // 10
	_listVertex.push_back(vec3(-ttt,  0.0,  size).normalize()); // 11

	// _listUV ==> TODO : very bad code ... get from viewBox ....
	_listUV.push_back(vec2(0.0, 0.0    )); // 0
	_listUV.push_back(vec2(0.0, 1.0    )); // 1
	_listUV.push_back(vec2(1.0, 0.0    )); // 2
	
	for (auto &elem : _listVertex) {
		EGE_INFO("plop : " << etk::to_string(elem));
	}
	
	if (_listFaces.exist(_materialName) == false) {
		FaceIndexing empty;
		_listFaces.add(_materialName, empty);
	}
	{
		FaceIndexing& tmpElement = _listFaces[_materialName];
		// 5 faces around point 0
		tmpElement.m_faces.push_back(Face(0,0, 11,1,  5,2));
		tmpElement.m_faces.push_back(Face(0,0,  5,1,  1,2));
		tmpElement.m_faces.push_back(Face(0,0,  1,1,  7,2));
		tmpElement.m_faces.push_back(Face(0,0,  7,1, 10,2));
		tmpElement.m_faces.push_back(Face(0,0, 10,1, 11,2));
		
		// 5 adjacent faces
		tmpElement.m_faces.push_back(Face( 1,0,  5,1, 9,2));
		tmpElement.m_faces.push_back(Face( 5,0, 11,1, 4,2));
		tmpElement.m_faces.push_back(Face(11,0, 10,1, 2,2));
		tmpElement.m_faces.push_back(Face(10,0,  7,1, 6,2));
		tmpElement.m_faces.push_back(Face( 7,0,  1,1, 8,2));
		
		// 5 faces around point 3
		tmpElement.m_faces.push_back(Face(3,0, 9,1, 4,2));
		tmpElement.m_faces.push_back(Face(3,0, 4,1, 2,2));
		tmpElement.m_faces.push_back(Face(3,0, 2,1, 6,2));
		tmpElement.m_faces.push_back(Face(3,0, 6,1, 8,2));
		tmpElement.m_faces.push_back(Face(3,0, 8,1, 9,2));
		
		// 5 adjacent faces 
		tmpElement.m_faces.push_back(Face(4,0, 9,1, 5,2));
		tmpElement.m_faces.push_back(Face(2,0, 4,1, 11,2));
		tmpElement.m_faces.push_back(Face(6,0, 2,1, 10,2));
		tmpElement.m_faces.push_back(Face(8,0, 6,1, 7,2));
		tmpElement.m_faces.push_back(Face(9,0, 8,1, 1,2));
		// refine triangles
		for (int i = 0; i < _recursionLevel; i++) {
			std::vector<Face> listFaces;
			for (auto &tri : tmpElement.m_faces) {
				// replace triangle by 4 triangles
				int32_t a = getMiddlePoint(_listVertex, tri.m_vertex[0], tri.m_vertex[1]);
				int32_t b = getMiddlePoint(_listVertex, tri.m_vertex[1], tri.m_vertex[2]);
				int32_t c = getMiddlePoint(_listVertex, tri.m_vertex[2], tri.m_vertex[0]);
				listFaces.push_back(Face(tri.m_vertex[0],0, a,1, c,2));
				listFaces.push_back(Face(tri.m_vertex[1],0, b,1, a,2));
				listFaces.push_back(Face(tri.m_vertex[2],0, c,1, b,2));
				listFaces.push_back(Face(a,0,               b,1, c,2));
			}
			tmpElement.m_faces = listFaces;
		}
		// update UV mapping with generic projection:
		_listUV.clear();
		for (auto &vert : _listVertex) {
			vec2 texturePos;
			// projection sur le plan XY:
			float proj = vert.x()*vert.x() + vert.y()*vert.y();
			proj = std::sqrt(proj);
			float angle = M_PI;
			if (proj != 0.0f) {
				angle = std::acos(std::abs(vert.x()) / proj);
			}
			if (vert.x()<0) {
				if (vert.y()<0) {
					angle = -M_PI + angle;
				} else {
					angle = M_PI - angle;
				}
			} else {
				if (vert.y()<0) {
					angle = -angle;
				}
			}
			//EGE_WARNING( "angle = " << (angle/M_PI*180.0f) << " from: vert=" << etk::to_string(vert) << " proj=" << proj );
			texturePos.setX(angle/(2.0f*M_PI)+0.5f);
			
			angle = std::acos(proj/1.0f);
			if (vert.z()<0) {
				angle = -angle;
			}
			//EGE_WARNING( "angle = " << (angle/M_PI*180.0f) << " from: vert=" << etk::to_string(vert) << " proj=" << proj );
			texturePos.setY(angle/(M_PI)+0.5);
			
			texturePos.setMax(vec2(0.0f, 0.0f));
			texturePos.setMin(vec2(1.0f, 1.0f));
			//EGE_WARNING("texturePosition = " << texturePos);
			_listUV.push_back(texturePos);
		}
		for (auto &face : tmpElement.m_faces) {
			float y0 = _listVertex[face.m_vertex[0]].y();
			float y1 = _listVertex[face.m_vertex[1]].y();
			float y2 = _listVertex[face.m_vertex[2]].y();
			face.m_uv[0] = face.m_vertex[0];
			face.m_uv[1] = face.m_vertex[1];
			face.m_uv[2] = face.m_vertex[2];
			// mauvaus coter ...
			if (    _listVertex[face.m_vertex[0]].x() < 0
			     || _listVertex[face.m_vertex[1]].x() < 0
			     || _listVertex[face.m_vertex[2]].x() < 0) {
				if (y0 < 0) {
					if (y1 < 0) {
						if (y2 >= 0) {
							face.m_uv[2] = addUV(_listUV, face.m_vertex[2], -1.0f);
						}
					} else {
						if (y2 < 0) {
							face.m_uv[1] = addUV(_listUV, face.m_vertex[1], -1.0f);;
						} else {
							face.m_uv[0] = addUV(_listUV, face.m_vertex[0], 1.0f);;
						}
					}
				} else {
					if (y1 < 0) {
						if (y2 < 0) {
							face.m_uv[0] = addUV(_listUV, face.m_vertex[0], -1.0f);
						} else {
							face.m_uv[1] = addUV(_listUV, face.m_vertex[1], 1.0f);
						}
					} else {
						if (y2 < 0) {
							face.m_uv[2] = addUV(_listUV, face.m_vertex[2], 1.0f);
						}
					}
				}
			}
		}
		for (auto &vert : _listVertex) {
			vert *=_size;
		}
	}
	
	
}
void IcoSphere::create(int recursionLevel)
{
	vertices.clear();
	lineIndices.clear();
	triangleIndices.clear();
	faces.clear();
	middlePointIndexCache.clear();
	index = 0;
 
	float t = (1.0f + Ogre::Math::Sqrt(5.0f)) / 2.0f;
 
	addVertex(Ogre::Vector3(-1.0f,  t,  0.0f));
	addVertex(Ogre::Vector3( 1.0f,  t,  0.0f));
	addVertex(Ogre::Vector3(-1.0f, -t,  0.0f));
	addVertex(Ogre::Vector3( 1.0f, -t,  0.0f));
 
	addVertex(Ogre::Vector3( 0.0f, -1.0f,  t));
	addVertex(Ogre::Vector3( 0.0f,  1.0f,  t));
	addVertex(Ogre::Vector3( 0.0f, -1.0f, -t));
	addVertex(Ogre::Vector3( 0.0f,  1.0f, -t));
 
	addVertex(Ogre::Vector3( t,  0.0f, -1.0f));
	addVertex(Ogre::Vector3( t,  0.0f,  1.0f));
	addVertex(Ogre::Vector3(-t,  0.0f, -1.0f));
	addVertex(Ogre::Vector3(-t,  0.0f,  1.0f));
 
	addFace(0, 11, 5);
	addFace(0, 5, 1);
	addFace(0, 1, 7);
	addFace(0, 7, 10);
	addFace(0, 10, 11);
 
	addFace(1, 5, 9);
	addFace(5, 11, 4);
	addFace(11, 10, 2);
	addFace(10, 7, 6);
	addFace(7, 1, 8);
 
	addFace(3, 9, 4);
	addFace(3, 4, 2);
	addFace(3, 2, 6);
	addFace(3, 6, 8);
	addFace(3, 8, 9);
 
	addFace(4, 9, 5);
	addFace(2, 4, 11);
	addFace(6, 2, 10);
	addFace(8, 6, 7);
	addFace(9, 8, 1);
 
	addLineIndices(1, 0);
	addLineIndices(1, 5);
	addLineIndices(1, 7);
	addLineIndices(1, 8);
	addLineIndices(1, 9);
 
	addLineIndices(2, 3);
	addLineIndices(2, 4);
	addLineIndices(2, 6);
	addLineIndices(2, 10);
	addLineIndices(2, 11);
 
	addLineIndices(0, 5);
	addLineIndices(5, 9);
	addLineIndices(9, 8);
	addLineIndices(8, 7);
	addLineIndices(7, 0);
 
	addLineIndices(10, 11);
	addLineIndices(11, 4);
	addLineIndices(4, 3);
	addLineIndices(3, 6);
	addLineIndices(6, 10);
 
	addLineIndices(0, 11);
	addLineIndices(11, 5);
	addLineIndices(5, 4);
	addLineIndices(4, 9);
	addLineIndices(9, 3);
	addLineIndices(3, 8);
	addLineIndices(8, 6);
	addLineIndices(6, 7);
	addLineIndices(7, 10);
	addLineIndices(10, 0);
 
	for (int i = 0; i < recursionLevel; i++)
	{
		std::list<TriangleIndices> faces2;
 
		for (std::list<TriangleIndices>::iterator j = faces.begin(); j != faces.end(); j++)
		{
			TriangleIndices f = *j;
			int a = getMiddlePoint(f.v1, f.v2);
			int b = getMiddlePoint(f.v2, f.v3);
			int c = getMiddlePoint(f.v3, f.v1);
 
			removeLineIndices(f.v1, f.v2);
			removeLineIndices(f.v2, f.v3);
			removeLineIndices(f.v3, f.v1);
 
			faces2.push_back(TriangleIndices(f.v1, a, c));
			faces2.push_back(TriangleIndices(f.v2, b, a));
			faces2.push_back(TriangleIndices(f.v3, c, b));
			faces2.push_back(TriangleIndices(a, b, c));
 
			addTriangleLines(f.v1, a, c);
			addTriangleLines(f.v2, b, a);
			addTriangleLines(f.v3, c, b);
		}
 
		faces = faces2;
	}
}
Пример #10
0
    void generate()
    {
        // create 12 vertices of a icosahedron
        double t = (1 + std::sqrt(5)) / 2;

        vertexList_.push_back(utymap::meshing::Vector3(-1, t, 0).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(1, t, 0).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(-1, -t, 0).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(1, -t, 0).normalized());

        vertexList_.push_back(utymap::meshing::Vector3(0, -1, t).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(0, 1, t).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(0., -1, -t).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(0, 1, -t).normalized());

        vertexList_.push_back(utymap::meshing::Vector3(t, 0, -1).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(t, 0, 1).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(-t, 0, -1).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(-t, 0, 1).normalized());

        // create 20 triangles of the icosahedron
        std::vector<TriangleIndices> faces;
        // 5 faces around point 0
        faces.push_back(TriangleIndices(0, 11, 5));
        faces.push_back(TriangleIndices(0, 5, 1));
        faces.push_back(TriangleIndices(0, 1, 7));
        faces.push_back(TriangleIndices(0, 7, 10));
        faces.push_back(TriangleIndices(0, 10, 11));

        // 5 adjacent faces
        faces.push_back(TriangleIndices(1, 5, 9));
        faces.push_back(TriangleIndices(5, 11, 4));
        if (!isSemiSphere_)
            faces.push_back(TriangleIndices(11, 10, 2));

        faces.push_back(TriangleIndices(10, 7, 6));
        faces.push_back(TriangleIndices(7, 1, 8));

        // 5 faces around point 3
        if (!isSemiSphere_)
        {
            faces.push_back(TriangleIndices(3, 9, 4));
            faces.push_back(TriangleIndices(3, 4, 2));
            faces.push_back(TriangleIndices(3, 2, 6));
            faces.push_back(TriangleIndices(3, 6, 8));
            faces.push_back(TriangleIndices(3, 8, 9));
        }

        // 5 adjacent faces
        faces.push_back(TriangleIndices(4, 9, 5));
        if (!isSemiSphere_)
        {
            faces.push_back(TriangleIndices(2, 4, 11));
            faces.push_back(TriangleIndices(6, 2, 10));
        }
        faces.push_back(TriangleIndices(8, 6, 7));
        faces.push_back(TriangleIndices(9, 8, 1));

        // refine triangles
        for (int i = 0; i < recursionLevel_; i++)
        {
            std::vector<TriangleIndices> faces2;
            for (const auto& tri : faces)
            {
                // replace triangle by 4 triangles
                auto a = getMiddlePoint(tri.V1, tri.V2);
                auto b = getMiddlePoint(tri.V2, tri.V3);
                auto c = getMiddlePoint(tri.V3, tri.V1);

                faces2.push_back(TriangleIndices(tri.V1, a, c));
                faces2.push_back(TriangleIndices(tri.V2, b, a));
                faces2.push_back(TriangleIndices(tri.V3, c, b));
                faces2.push_back(TriangleIndices(a, b, c));
            }
            faces = faces2;
        }
        generateMesh(faces);

        // clear state to allow reusage
        middlePointIndexCache_.clear();
        vertexList_.clear();
    }
Пример #11
0
		void generateIcoSphere(std::size_t recursion, std::vector<glm::vec3> &vertex, std::vector<unsigned int> &indices)
		{
			idxHash_t					middlePoints;
			std::size_t					currentIdx = 0;

			// create 12 vertices of a icosahedron
			const float t = (1.0f + (float)std::sqrt(5.0f)) / 2.0f;

			vertex =
			{
				glm::normalize(glm::vec3(-1, t, 0)),
				glm::normalize(glm::vec3(1, t, 0)),
				glm::normalize(glm::vec3(-1, -t, 0)),
				glm::normalize(glm::vec3(1, -t, 0)),
				glm::normalize(glm::vec3(0, -1, t)),
				glm::normalize(glm::vec3(0, 1, t)),
				glm::normalize(glm::vec3(0, -1, -t)),
				glm::normalize(glm::vec3(0, 1, -t)),
				glm::normalize(glm::vec3(t, 0, -1)),
				glm::normalize(glm::vec3(t, 0, 1)),
				glm::normalize(glm::vec3(-t, 0, -1)),
				glm::normalize(glm::vec3(-t, 0, 1))
			};

			indices =
			{
				0, 11, 5,
				0, 5, 1,
				0, 1, 7,
				0, 7, 10,
				0, 10, 11,
				1, 5, 9,
				5, 11, 4,
				11, 10, 2,
				10, 7, 6,
				7, 1, 8,
				3, 9, 4,
				3, 4, 2,
				3, 2, 6,
				3, 6, 8,
				3, 8, 9,
				4, 9, 5,
				2, 4, 11,
				6, 2, 10,
				8, 6, 7,
				9, 8, 1
			};

			// refine triangles
			for (int i = 0; i < recursion; i++)
			{
				std::vector<glm::uvec3>			idTab2;

				for (int i = 0; i < indices.size(); i += 3)
				{
					// replace triangle by 4 triangles

					uint32_t a = static_cast<uint32_t>(getMiddlePoint(vertex, middlePoints, indices[i + 0], indices[i + 1]));
					uint32_t b = static_cast<uint32_t>(getMiddlePoint(vertex, middlePoints, indices[i + 1], indices[i + 2]));
					uint32_t c = static_cast<uint32_t>(getMiddlePoint(vertex, middlePoints, indices[i + 2], indices[i + 0]));

					idTab2.push_back(glm::u32vec3(indices[i + 0], a, c));
					idTab2.push_back(glm::u32vec3(indices[i + 1], b, a));
					idTab2.push_back(glm::u32vec3(indices[i + 2], c, b));
					idTab2.push_back(glm::u32vec3(a, b, c));
				}
				indices.resize(idTab2.size() * 3);
				memcpy(indices.data(), idTab2.data(), idTab2.size() * 3 * sizeof(unsigned int));
			}
		}
Пример #12
0
Model* Primative::getSphere(glm::vec3 color, float recursionLevel){
   std::vector<glm::vec3> vertices;
   std::vector<unsigned int> indices;
   
   // create 12 vertices of a icosahedron
   float t = (1.0 + sqrtf(5.0)) / 2.0;
   
   addVertex(vertices, glm::vec3(-1,  t,  0));
   addVertex(vertices, glm::vec3( 1,  t,  0));
   addVertex(vertices, glm::vec3(-1, -t,  0));
   addVertex(vertices, glm::vec3( 1, -t,  0));
   
   addVertex(vertices, glm::vec3( 0, -1,  t));
   addVertex(vertices, glm::vec3( 0,  1,  t));
   addVertex(vertices, glm::vec3( 0, -1, -t));
   addVertex(vertices, glm::vec3( 0,  1, -t));
   
   addVertex(vertices, glm::vec3( t,  0, -1));
   addVertex(vertices, glm::vec3( t,  0,  1));
   addVertex(vertices, glm::vec3(-t,  0, -1));
   addVertex(vertices, glm::vec3(-t,  0,  1));
   
   // 5 faces around point 0
   indices.push_back(0);
   indices.push_back(11);
   indices.push_back(5);
   
   indices.push_back(0);
   indices.push_back(5);
   indices.push_back(1);
   
   indices.push_back(0);
   indices.push_back(1);
   indices.push_back(7);
   
   indices.push_back(0);
   indices.push_back(7);
   indices.push_back(10);
   
   indices.push_back(0);
   indices.push_back(10);
   indices.push_back(11);
   
   // 5 adjacent faces
   indices.push_back(1);
   indices.push_back(5);
   indices.push_back(9);
   
   indices.push_back(5);
   indices.push_back(11);
   indices.push_back(4);
   
   indices.push_back(11);
   indices.push_back(10);
   indices.push_back(2);
   
   indices.push_back(10);
   indices.push_back(7);
   indices.push_back(6);
   
   indices.push_back(7);
   indices.push_back(1);
   indices.push_back(8);
   
   // 5 faces around point 3
   indices.push_back(3);
   indices.push_back(9);
   indices.push_back(4);
   
   indices.push_back(3);
   indices.push_back(4);
   indices.push_back(2);
   
   indices.push_back(3);
   indices.push_back(2);
   indices.push_back(6);
   
   indices.push_back(3);
   indices.push_back(6);
   indices.push_back(8);
   
   indices.push_back(3);
   indices.push_back(8);
   indices.push_back(9);
   
   // 5 adjacent faces
   
   indices.push_back(4);
   indices.push_back(9);
   indices.push_back(5);
   
   indices.push_back(2);
   indices.push_back(4);
   indices.push_back(11);
   
   indices.push_back(6);
   indices.push_back(2);
   indices.push_back(10);
   
   indices.push_back(8);
   indices.push_back(6);
   indices.push_back(7);
   
   indices.push_back(9);
   indices.push_back(8);
   indices.push_back(1);
   
   // refine triangles
   for (int j = 0; j < recursionLevel; j++)
   {
      std::vector<unsigned int> newIndices;
      for(int i=0; (i+2)<indices.size();i+=3)
      {
         // replace triangle by 4 triangles
         unsigned int a = getMiddlePoint(vertices, indices[i], indices[i+1]);
         unsigned int b = getMiddlePoint(vertices,indices[i+1], indices[i+2]);
         unsigned int c = getMiddlePoint(vertices,indices[i+2], indices[i]);
         
         newIndices.push_back(indices[i]);
         newIndices.push_back(a);
         newIndices.push_back(c);
         
         newIndices.push_back(indices[i+1]);
         newIndices.push_back(b);
         newIndices.push_back(a);
         
         newIndices.push_back(indices[i+2]);
         newIndices.push_back(c);
         newIndices.push_back(b);
         
         newIndices.push_back(a);
         newIndices.push_back(b);
         newIndices.push_back(c);
      }
      
      indices = newIndices;
   }
   
   
   std::vector<glm::vec3> colors(vertices.size(),color);
   Model *m = new Model(vertices, vertices,  colors, indices);
   middlePointIndexCache.clear();
   return m;
};
Пример #13
0
// Initialization code
void init()
{
	// Initializes the glew library
	glewInit();

	// Enables the depth test, which you will want in most cases. You can disable this in the render loop if you need to.
	glEnable(GL_DEPTH_TEST);

	// An element array, which determines which of the vertices to display in what order. This is sometimes known as an index array.
	GLuint elements[] = {
		0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
	};
	// These are the indices for an icosahedron.

	for (int i = 0; i < 60; i++)
	{
		theElements.push_back(elements[i]);
	}

	// Formula for creating the 12 vertices of an icosahedron.
	double t = (1.0 + sqrt(5.0)) / 2.0;

	// Create an std::vector and put our vertices into it. These are just hardcoded values here defined once.
	// These are the vertices for an icosahedron.
	vertices.push_back(VertexFormat(glm::vec3(-1.0, t, 0.0),
		glm::vec4(1.0, 0.0, 0.0, 1.0))); //red
	vertices.push_back(VertexFormat(glm::vec3(1.0, t, 0.0),
		glm::vec4(1.0, 0.0, 0.0, 1.0))); //red
	vertices.push_back(VertexFormat(glm::vec3(-1.0, -t, 0.0),
		glm::vec4(1.0, 0.0, 1.0, 1.0))); //yellow
	vertices.push_back(VertexFormat(glm::vec3(1.0, -t, 0.0),
		glm::vec4(1.0, 0.0, 1.0, 1.0))); //yellow
	vertices.push_back(VertexFormat(glm::vec3(0.0, -1.0, t),
		glm::vec4(0.0, 1.0, 1.0, 1.0))); //cyan
	vertices.push_back(VertexFormat(glm::vec3(0.0, 1.0, t),
		glm::vec4(0.0, 1.0, 1.0, 1.0))); //cyan
	vertices.push_back(VertexFormat(glm::vec3(-0.0, -1.0, -t),
		glm::vec4(0.0, 1.0, 0.0, 1.0))); //blue
	vertices.push_back(VertexFormat(glm::vec3(-0.0, 1.0, -t),
		glm::vec4(0.0, 1.0, 0.0, 1.0))); //blue
	vertices.push_back(VertexFormat(glm::vec3(t, 0.0, -1.0),
		glm::vec4(0.0, 1.0, 1.0, 1.0))); //cyan
	vertices.push_back(VertexFormat(glm::vec3(t, 0.0, 1.0),
		glm::vec4(0.0, 1.0, 1.0, 1.0))); //cyan
	vertices.push_back(VertexFormat(glm::vec3(-t, 0.0, -1.0),
		glm::vec4(0.0, 1.0, 0.0, 1.0))); //blue
	vertices.push_back(VertexFormat(glm::vec3(-t, 0.0, 1.0),
		glm::vec4(0.0, 1.0, 0.0, 1.0))); //blue

	for (int i = 0; i < vertices.size(); i++)
	{
		double length = sqrt(vertices[i].position.x * vertices[i].position.x + vertices[i].position.y * vertices[i].position.y + vertices[i].position.z * vertices[i].position.z);
		vertices[i] = VertexFormat(glm::vec3(vertices[i].position.x / length, vertices[i].position.y / length, vertices[i].position.z / length), glm::vec4(((float)(rand() % 100)) / 99.0f, ((float)(rand() % 100)) / 99.0f, ((float)(rand() % 100)) / 99.0f, 1.0f));
		// Normalize the vertices so they all lie on the outer sphere surrounding the icosahedron.
	}

	const int NUM_REVISIONS = 5;

	for (int i = 0; i < NUM_REVISIONS; i++)
	{
		std::vector<VertexFormat> vertices2;
		std::vector<GLuint> theElements2;

		for (int j = 0; j < theElements.size(); j += 3)
		{
			unsigned int a = getMiddlePoint(theElements[j], theElements[j + 1]);
			unsigned int b = getMiddlePoint(theElements[j + 1], theElements[j + 2]);
			unsigned int c = getMiddlePoint(theElements[j + 2], theElements[j]);

			vertices2.push_back(vertices[theElements[j]]);
			theElements2.push_back(j * 2);
			vertices2.push_back(vertices[a]);
			theElements2.push_back((j * 2) + 1);
			vertices2.push_back(vertices[c]);
			theElements2.push_back((j * 2) + 2);
			vertices2.push_back(vertices[theElements[j + 1]]);
			theElements2.push_back((j * 2) + 3);
			vertices2.push_back(vertices[b]);
			theElements2.push_back((j * 2) + 4);
			//vertices2.push_back(vertices[a]);
			theElements2.push_back((j * 2) + 1);
			vertices2.push_back(vertices[theElements[j + 2]]);
			theElements2.push_back((j * 2) + 5);
			//vertices2.push_back(vertices[c]);
			theElements2.push_back((j * 2) + 2);
			//vertices2.push_back(vertices[b]);
			theElements2.push_back((j * 2) + 4);
			//vertices2.push_back(vertices[a]);
			theElements2.push_back((j * 2) + 1);
			//vertices2.push_back(vertices[b]);
			theElements2.push_back((j * 2) + 4);
			//vertices2.push_back(vertices[c]);
			theElements2.push_back((j * 2) + 2);
		}

		vertices = vertices2;
		theElements = theElements2;
	}

	// Create our icosphere model from the calculated data.
	icosphere = new Model(vertices.size(), vertices.data(), theElements.size(), theElements.data());

	// Create two GameObjects based off of the icosphere model (note that they are both holding pointers to the icosphere, not actual copies of the icosphere vertex data).
	obj1 = new GameObject(icosphere);

	// Set beginning properties of GameObjects.
	obj1->SetVelocity(glm::vec3(0, 0.0f, 0.0f)); // The first object doesn't move.
	obj1->SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
	obj1->SetScale(glm::vec3(0.90f, 0.90f, 0.90f));

	// Read in the shader code from a file.
	std::string vertShader = readShader("VertexShader.glsl");
	std::string fragShader = readShader("FragmentShader.glsl");

	// createShader consolidates all of the shader compilation code
	vertex_shader = createShader(vertShader, GL_VERTEX_SHADER);
	fragment_shader = createShader(fragShader, GL_FRAGMENT_SHADER);

	// A shader is a program that runs on your GPU instead of your CPU. In this sense, OpenGL refers to your groups of shaders as "programs".
	// Using glCreateProgram creates a shader program and returns a GLuint reference to it.
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);		// This attaches our vertex shader to our program.
	glAttachShader(program, fragment_shader);	// This attaches our fragment shader to our program.

	// This links the program, using the vertex and fragment shaders to create executables to run on the GPU.
	glLinkProgram(program);
	// End of shader and program creation

	// This gets us a reference to the uniform variable in the vertex shader, which is called "MVP".
	// We're using this variable as a 4x4 transformation matrix
	// Only 2 parameters required: A reference to the shader program and the name of the uniform variable within the shader code.
	uniMVP = glGetUniformLocation(program, "MVP");

	// Creates the view matrix using glm::lookAt.
	// First parameter is camera position, second parameter is point to be centered on-screen, and the third paramter is the up axis.
	view = glm::lookAt(	glm::vec3(0.0f, 0.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

	// Creates a projection matrix using glm::perspective.
	// First parameter is the vertical FoV (Field of View), second paramter is the aspect ratio, 3rd parameter is the near clipping plane, 4th parameter is the far clipping plane.
	proj = glm::perspective(45.0f, 800.0f / 600.0f, 0.1f, 100.0f);

	// Allows us to make one less calculation per frame, as long as we don't update the projection and view matrices every frame.
	PV = proj * view;

	// Create your MVP matrices based on the objects' transforms.
	MVP = PV * *obj1->GetTransform();

	// Calculate the Axis-Aligned Bounding Box for your object.
	obj1->CalculateAABB();

	// This is not necessary, but I prefer to handle my vertices in the clockwise order. glFrontFace defines which face of the triangles you're drawing is the front.
	// Essentially, if you draw your vertices in counter-clockwise order, by default (in OpenGL) the front face will be facing you/the screen. If you draw them clockwise, the front face
	// will face away from you. By passing in GL_CW to this function, we are saying the opposite, and now the front face will face you if you draw in the clockwise order.
	// If you don't use this, just reverse the order of the vertices in your array when you define them so that you draw the points in a counter-clockwise order.
	glFrontFace(GL_CW);

	// This is also not necessary, but more efficient and is generally good practice. By default, OpenGL will render both sides of a triangle that you draw. By enabling GL_CULL_FACE,
	// we are telling OpenGL to only render the front face. This means that if you rotated the triangle over the X-axis, you wouldn't see the other side of the triangle as it rotated.
	glEnable(GL_CULL_FACE);

	// Determines the interpretation of polygons for rasterization. The first parameter, face, determines which polygons the mode applies to.
	// The face can be either GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK
	// The mode determines how the polygons will be rasterized. GL_POINT will draw points at each vertex, GL_LINE will draw lines between the vertices, and
	// GL_FILL will fill the area inside those lines.
	glPolygonMode(GL_FRONT, GL_FILL);
}