MeshVertex MeshAnimatedVertex::GetFinalVertex(void) { glm::vec3 finalPosition = glm::vec3 ( mAnimatedVertices->mFinalPositionArray[3 * mIndex], mAnimatedVertices->mFinalPositionArray[3 * mIndex + 1], mAnimatedVertices->mFinalPositionArray[3 * mIndex + 2] ); glm::vec2 finalTexCoord = glm::vec2 ( mAnimatedVertices->mTexCoordArray[2 * mIndex], mAnimatedVertices->mTexCoordArray[2 * mIndex + 1] ); glm::vec3 finalTangent = glm::vec3 ( mAnimatedVertices->mFinalTangentArray[3 * mIndex], mAnimatedVertices->mFinalTangentArray[3 * mIndex + 1], mAnimatedVertices->mFinalTangentArray[3 * mIndex + 2] ); glm::vec3 finalBitangent = glm::vec3 ( mAnimatedVertices->mFinalBitangentArray[3 * mIndex], mAnimatedVertices->mFinalBitangentArray[3 * mIndex + 1], mAnimatedVertices->mFinalBitangentArray[3 * mIndex + 2] ); glm::vec3 finalNormal = glm::vec3 ( mAnimatedVertices->mFinalNormalArray[3 * mIndex], mAnimatedVertices->mFinalNormalArray[3 * mIndex + 1], mAnimatedVertices->mFinalNormalArray[3 * mIndex + 2] ); return MeshVertex(finalPosition, finalTexCoord, finalTangent, finalBitangent, finalNormal); }
/** Constructor from vector of MeshVertex and triangles @param[in] vertices a list of vertices @param[in] the indices of the vertices that should be used, the ones that are not in this list are ignored @param[in] triangles a list of the triangles with indexed vertices */ Mesh::Mesh(vector<glm::vec3> vertices,vector<int> usedIndices,vector<int> triangles) : mvbo{0}, vao{0}, ibo{0}, scaleFactor{1} { for (int i = 0; i < usedIndices.size(); i++) { meshVertices.push_back(MeshVertex(vertices[i],glm::vec2(0,0),glm::vec3(0,0,0))); } for (int i = 0; i < triangles.size(); i++) { triangles.push_back(triangles[i]); } #ifdef GUINITY_DEBUG nCount++; #endif createBuffers(); }
/** Constructor from array of vertices, normal points, uvs and triangle indices. The arrays should contain 3 indices per vertex for the position and normal points and 2 indices per vertex for the UV. The triangles array uses 3 elements per triangle. @param[in] vertices the vertices, 3 elements per vertex @param[in] normalPoints the normals, 3 elements per vertex @param[in] uvs the UVs, 2 elements per vertex @param[in] triangles the triangles that form the Mesh @param[in] nVertices the vertex count @param[in] nTriangles the size of the triangles array */ Mesh::Mesh(float* vertices, float* normalPoints, float* uv, unsigned int *triangles, int nVertices, int nTriangles) : mvbo{0}, vao{0}, ibo{0}, scaleFactor{1} { for (int i = 0; i < nVertices; i++) { meshVertices.push_back(MeshVertex(glm::vec3(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), glm::vec2(uv[i * 3], uv[i * 3 + 1]), glm::vec3(normalPoints[i * 3], normalPoints[i * 3 + 1], normalPoints[i * 3 + 2]))); } for (int i = 0; i < nTriangles; i++) { this->triangles.push_back(triangles[i]); } #ifdef GUINITY_DEBUG nCount++; #endif createBuffers(); }
/** Adds a new vertex to the mesh @param[in] position the position @param[in] uv the UV coordinate @param[in] normal the normal */ void Mesh::addVertex(glm::vec3 position, glm::vec2 uv, glm::vec3 normal) { meshVertices.push_back(MeshVertex(position, uv, normal)); }
namespace mimp { template<> MeshVertex VertexLess<MeshVertex>::mFind = MeshVertex(); template<> STDNAME::vector<MeshVertex > *VertexLess<MeshVertex>::mList=0; template<> bool VertexLess<MeshVertex>::operator()(MiI32 v1,MiI32 v2) const { const MeshVertex& a = Get(v1); const MeshVertex& b = Get(v2); if ( a.mPos[0] < b.mPos[0] ) return true; if ( a.mPos[0] > b.mPos[0] ) return false; if ( a.mPos[1] < b.mPos[1] ) return true; if ( a.mPos[1] > b.mPos[1] ) return false; if ( a.mPos[2] < b.mPos[2] ) return true; if ( a.mPos[2] > b.mPos[2] ) return false; if ( a.mNormal[0] < b.mNormal[0] ) return true; if ( a.mNormal[0] > b.mNormal[0] ) return false; if ( a.mNormal[1] < b.mNormal[1] ) return true; if ( a.mNormal[1] > b.mNormal[1] ) return false; if ( a.mNormal[2] < b.mNormal[2] ) return true; if ( a.mNormal[2] > b.mNormal[2] ) return false; if ( a.mColor < b.mColor ) return true; if ( a.mColor > b.mColor ) return false; if ( a.mTexel1[0] < b.mTexel1[0] ) return true; if ( a.mTexel1[0] > b.mTexel1[0] ) return false; if ( a.mTexel1[1] < b.mTexel1[1] ) return true; if ( a.mTexel1[1] > b.mTexel1[1] ) return false; if ( a.mTexel2[0] < b.mTexel2[0] ) return true; if ( a.mTexel2[0] > b.mTexel2[0] ) return false; if ( a.mTexel2[1] < b.mTexel2[1] ) return true; if ( a.mTexel2[1] > b.mTexel2[1] ) return false; if ( a.mTexel3[0] < b.mTexel3[0] ) return true; if ( a.mTexel3[0] > b.mTexel3[0] ) return false; if ( a.mTexel3[1] < b.mTexel3[1] ) return true; if ( a.mTexel3[1] > b.mTexel3[1] ) return false; if ( a.mTexel4[0] < b.mTexel4[0] ) return true; if ( a.mTexel4[0] > b.mTexel4[0] ) return false; if ( a.mTexel4[1] < b.mTexel4[1] ) return true; if ( a.mTexel4[1] > b.mTexel4[1] ) return false; if ( a.mTangent[0] < b.mTangent[0] ) return true; if ( a.mTangent[0] > b.mTangent[0] ) return false; if ( a.mTangent[1] < b.mTangent[1] ) return true; if ( a.mTangent[1] > b.mTangent[1] ) return false; if ( a.mTangent[2] < b.mTangent[2] ) return true; if ( a.mTangent[2] > b.mTangent[2] ) return false; if ( a.mBiNormal[0] < b.mBiNormal[0] ) return true; if ( a.mBiNormal[0] > b.mBiNormal[0] ) return false; if ( a.mBiNormal[1] < b.mBiNormal[1] ) return true; if ( a.mBiNormal[1] > b.mBiNormal[1] ) return false; if ( a.mBiNormal[2] < b.mBiNormal[2] ) return true; if ( a.mBiNormal[2] > b.mBiNormal[2] ) return false; if ( a.mWeight[0] < b.mWeight[0] ) return true; if ( a.mWeight[0] > b.mWeight[0] ) return false; if ( a.mWeight[1] < b.mWeight[1] ) return true; if ( a.mWeight[1] > b.mWeight[1] ) return false; if ( a.mWeight[2] < b.mWeight[2] ) return true; if ( a.mWeight[2] > b.mWeight[2] ) return false; if ( a.mWeight[3] < b.mWeight[3] ) return true; if ( a.mWeight[3] > b.mWeight[3] ) return false; if ( a.mBone[0] < b.mBone[0] ) return true; if ( a.mBone[0] > b.mBone[0] ) return false; if ( a.mBone[1] < b.mBone[1] ) return true; if ( a.mBone[1] > b.mBone[1] ) return false; if ( a.mBone[2] < b.mBone[2] ) return true; if ( a.mBone[2] > b.mBone[2] ) return false; if ( a.mBone[3] < b.mBone[3] ) return true; if ( a.mBone[3] > b.mBone[3] ) return false; if ( a.mRadius < b.mRadius ) return true; if ( a.mRadius > b.mRadius ) return false; return false; }; }; // end of name space
std::unique_ptr<Mesh> MeshUtility::MakeSphere(float radius, unsigned int subdivisions) { if (subdivisions > ModelUtility::MAX_SPHERE_SUBDIVISIONS) { subdivisions = ModelUtility::MAX_SPHERE_SUBDIVISIONS; } std::unique_ptr<Mesh> octahedron = MeshUtility::MakeOctahedron(radius); std::vector<Triangle3D_t> initialTriangles; Transformation identity; for (std::size_t iFace = 0, numFaces = octahedron->NumFaces(); iFace < numFaces; ++iFace) { initialTriangles.push_back(octahedron->GetFaceTriangle(iFace, identity)); } std::vector<Triangle3D_t> subdividedTriangles; for (const Triangle3D_t& triangle : initialTriangles) { ModelUtility::SubdivideTriangle(triangle, subdividedTriangles, subdivisions); } std::vector<std::vector<MeshVertex>> trianglesOnSphere; trianglesOnSphere.reserve(subdividedTriangles.size()); std::vector<MeshVertex> triangleOnSphere(3, MeshVertex(Color::White(), Locus::TextureCoordinate())); Plane fixSmearPlane(Vec3D::ZeroVector(), Vec3D::NegativeZAxis()); for (const Triangle3D_t& triangle : subdividedTriangles) { for (std::size_t i = 0; i < Triangle3D_t::NumPointsOnATriangle; ++i) { triangleOnSphere[i].position = NormVector(triangle[i]) * radius; triangleOnSphere[i].textureCoordinate = MeshUtility::SphericalUVMapping(triangleOnSphere[i].position); } // //HACK: fixing smearing that occurs at the boundary where U = 0.0 or 1.0. The //spherical UV mapping algorithm always returns U = 1.0 at the boundary. Here //we find if the triangle that was just generated is at this boundary. The "real" //way to do it would be to unwrap the sphere or make a UV sphere. // Plane::IntersectionQuery intersectionQuery = fixSmearPlane.triangleIntersectionTest(triangle); if ((intersectionQuery == Plane::IntersectionQuery::None) || (intersectionQuery == Plane::IntersectionQuery::Positive)) { for (std::size_t i = 0; i < Triangle3D_t::NumPointsOnATriangle; ++i) { if (FEqual<float>(triangleOnSphere[i].textureCoordinate.x, 1.0f)) { triangleOnSphere[i].textureCoordinate.x = 0.0f; } } } trianglesOnSphere.push_back(triangleOnSphere); } return std::make_unique<Mesh>(trianglesOnSphere); }
void MS3DToMesh::Vertex( const MS3D::Vertex & vertex ) { float empty [] = { 0.0f, 0.0f, 0.0f }; vertices.push_back( MeshVertex( vertex.vertex, empty, vertex.boneId ) ); }