Пример #1
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;
		}
	}
	
	
}
Пример #2
0
/**
 * @param circle a path in the (x,y)-plane.
 */
void Extrusion::init(const Path& path, const Path& circle, uint32_t segments, uint32_t pieces, double twists) {
    assert(pieces > 2);

    Vector* cp = (Vector*)::alloca(sizeof(Vector)*segments);
    double last_t = 0;
    for (uint32_t p = 0; p < pieces; p++) {
	    double t = double(p) / double(pieces);
	    Vector c = path.getPoint(t);
	    Vector n = path.getTangent(t);
        
	    circle.getPoints(segments,cp);
        
	    // Transform points
	    double twist_angle = double(p) * 360.0 * twists /  double(pieces);
	    Matrix matrix = Matrix::matrixRotate(Vector(0,0,1), twist_angle) * 
	                    Matrix::matrixOrient(n).inverse() * 
	    		        Matrix::matrixTranslate(c);
        
	    for(uint32_t i = 0; i < segments; i++) {
	        cp[i] = matrix * cp[i];
	    }
        
	    for(uint32_t i = 0; i < segments; i++) {
	        uint32_t k = addVertex(cp[i]);
	        assert(k == p*segments + i);
	    }
        
	    if (p > 0) {
	        uint32_t p1 = p - 1;
	        for(uint32_t i = 0; i < segments; i++) {
	    	    uint32_t j = (i + 1) % segments;
	    	    double ti = double(i) / double(segments);
	    	    double tj = double(j) / double(segments);
        
                uint32_t a = addUV(Vector2(last_t,tj));
                uint32_t b = addUV(Vector2(t,tj));
                uint32_t c = addUV(Vector2(t,ti));
	    	    addTriangle(p1*segments+j, p*segments+j, p*segments+i,
	    	        a,b,c);
                a = addUV(Vector2(last_t,ti));
                b = addUV(Vector2(last_t,tj));
                c = addUV(Vector2(t,ti));
	    	    addTriangle(p1*segments+i, p1*segments+j, p*segments+i,
	    	        a,b,c);
	        }
	    }
	    last_t = t;
    }
    if (path.isClosed()) {
	    int p1 = pieces-1;
	    for(uint32_t i = 0; i < segments; i++) {
	        uint32_t j = (i + 1) % segments;
	        double ti = double(i) / double(segments);
	        double tj = double(j) / double(segments);
        
            uint32_t a = addUV(Vector2(last_t,tj));
            uint32_t b = addUV(Vector2(1,tj));
            uint32_t c = addUV(Vector2(1,ti));
	        addTriangle(p1*segments+j,j,i,
	    	    a,b,c);
            a = addUV(Vector2(last_t,ti));
            b = addUV(Vector2(last_t,tj));
            c = addUV(Vector2(1,ti));
	        addTriangle(p1*segments+i,p1*segments+j,i,
	    	    a,b,c);
	    }
    } else {
	// TODO: Add begin and end discs

    }
}