From 19990e48f4f790a90091bf902a01dde6597a4453 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Mon, 19 Aug 2024 18:23:09 +0300 Subject: [PATCH] using only the neeeded number of vertex positions --- box.cpp | 8 ++--- mesh.cpp | 22 +++++++------ meshData.cpp | 38 ++++++++++++---------- meshData.h | 36 ++++++++++++++++++--- model.cpp | 6 ++-- quad.cpp | 25 ++++++++------- rayCaster.cpp | 4 +-- xmlModelReader.cpp | 78 ++++++++++++++++++++++++++++++++-------------- 8 files changed, 145 insertions(+), 72 deletions(-) diff --git a/box.cpp b/box.cpp index f69613a..118cf2f 100755 --- a/box.cpp +++ b/box.cpp @@ -63,14 +63,14 @@ namespace vb01{ MeshData::Vertex *vertices = new MeshData::Vertex[3 * numTris]; for(int i = 0; i < 3 * numTris; i++){ - MeshData::Vertex v; - v.pos = pos[data[3 * i]]; - v.norm = norm[data[3 * i + 1]]; + MeshData::Vertex v; + v.pos = &pos[data[3 * i]]; + v.norm = &norm[data[3 * i + 1]]; v.uv = tex[data[3 * i + 2]]; vertices[i] = v; indices[i] = i; } - meshBase = MeshData(vertices, indices, numTris); + meshBase = MeshData((Vector3*)pos, nullptr, nullptr, nullptr, 8, (Vector3*)norm, vertices, indices, numTris); } } diff --git a/mesh.cpp b/mesh.cpp index c8c8a25..1ac93b4 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -44,31 +44,35 @@ namespace vb01{ glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); - u32 size = sizeof(MeshData::Vertex); + u32 size = sizeof(MeshData::OldVertex); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, 3 * meshBase.numTris * size, meshBase.vertices, GL_DYNAMIC_DRAW); + + MeshData::OldVertex *glVertData = meshBase.toGlVerts(); + glBufferData(GL_ARRAY_BUFFER, 3 * meshBase.numTris * size, glVertData, GL_DYNAMIC_DRAW); + delete glVertData; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * meshBase.numTris * sizeof(u32), meshBase.indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size, (void*)0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, norm))); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::OldVertex, norm))); glEnableVertexAttribArray(1); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, uv))); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::OldVertex, uv))); glEnableVertexAttribArray(2); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, tan))); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::OldVertex, tan))); glEnableVertexAttribArray(3); - glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, biTan))); + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::OldVertex, biTan))); glEnableVertexAttribArray(4); - glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, weights))); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::OldVertex, weights))); glEnableVertexAttribArray(5); - glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, boneIndices))); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::OldVertex, boneIndices))); glEnableVertexAttribArray(6); for(int i = 0; i < meshBase.numShapeKeys; i++){ - glVertexAttribPointer(7 + i, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, shapeKeyOffsets) + 3 * i * sizeof(float))); + glVertexAttribPointer(7 + i, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::OldVertex, shapeKeyOffsets) + 3 * i * sizeof(float))); glEnableVertexAttribArray(7 + i); } } diff --git a/meshData.cpp b/meshData.cpp index b5223c9..7ae627d 100644 --- a/meshData.cpp +++ b/meshData.cpp @@ -17,22 +17,28 @@ namespace vb01{ } } - MeshData::ShapeKey::ShapeKey(string name, float value, float minValue, float maxValue) : Animatable(Animatable::SHAPE_KEY, name){ - this->name = name; - this->value = value; - this->minValue = minValue; - this->maxValue = maxValue; - } + MeshData::OldVertex* MeshData::toGlVerts(){ + int numVertices = 3 * numTris; + OldVertex *vertData = new OldVertex[numVertices]; - MeshData::MeshData(Vertex *vertices, u32 *indices, int numTris, string attachableName, string *vertexGroups, int numVertexGroups, string fullSkeletonName, ShapeKey *shapeKeys, int numShapeKeys){ - this->vertices = vertices; - this->indices = indices; - this->numTris = numTris; - this->attachableName = attachableName; - this->vertexGroups = vertexGroups; - this->numVertexGroups = numVertexGroups; - this->fullSkeletonName = fullSkeletonName; - this->shapeKeys = shapeKeys; - this->numShapeKeys = numShapeKeys; + for(int i = 0; i < numVertices; i++){ + vertData[i].pos = *vertices[i].pos; + vertData[i].norm = *vertices[i].norm; + vertData[i].tan = vertices[i].tan; + vertData[i].biTan = vertices[i].biTan; + vertData[i].uv = vertices[i].uv; + + if(weights){ + for(int j = 0; j < 4; j++){ + vertData[i].weights[j] = vertices[i].weights[j]; + vertData[i].boneIndices[j] = vertices[i].boneIndices[j]; + } + + } + + //if(shapeKeyOffsets) for(int j = 0; j < 100; j++) vertData[i].shapeKeyOffsets[j] = vertices[i].shapeKeyOffsets[j]; + } + + return vertData; } } diff --git a/meshData.h b/meshData.h index 783f60d..a8738d8 100644 --- a/meshData.h +++ b/meshData.h @@ -14,12 +14,12 @@ namespace vb01{ std::string name; float minValue, value, maxValue; - ShapeKey(std::string, float, float, float); + ShapeKey(std::string n, float v, float mnv, float mxv) : name(n), value(v), minValue(mnv), maxValue(mxv), Animatable(Animatable::SHAPE_KEY, name){} ShapeKey() : Animatable(Animatable::SHAPE_KEY){} void animate(float, KeyframeChannel); }; - struct Vertex{ + struct OldVertex{ Vector3 pos, norm, tan, biTan; Vector2 uv; float weights[4]{0, 0, 0, 0}; @@ -27,15 +27,43 @@ namespace vb01{ Vector3 shapeKeyOffsets[100]; }; + struct Vertex{ + Vector3 *pos = nullptr, *norm = nullptr, tan, biTan; + Vector2 uv; + float *weights = nullptr; + int *boneIndices = nullptr; + Vector3 *shapeKeyOffsets = nullptr; + }; + + OldVertex* toGlVerts(); + + Vector3 *positions = nullptr, *normals = nullptr, **shapeKeyOffsets = nullptr; + float **weights = nullptr; + int **boneIndices = nullptr; Vertex *vertices; std::string *vertexGroups = nullptr; ShapeKey *shapeKeys = nullptr; u32 *indices, VAO, VBO, EBO; - int numTris, numVertexGroups = 0, numShapeKeys = 0; + int numPos, numTris, numVertexGroups = 0, numShapeKeys = 0; std::string attachableName = "", fullSkeletonName = ""; MeshData(){} - MeshData(Vertex*, u32*, int, std::string = "", std::string *vg = nullptr, int = 0, std::string = "", ShapeKey *sk = nullptr, int = 0); + MeshData(Vector3 *pos, float **w, int **bi, Vector3 **sko, int np, Vector3 *norm, Vertex *vert, u32 *ind, int nt, std::string an = "", std::string *vg = nullptr, int nvg = 0, std::string fsn = "", ShapeKey *sk = nullptr, int nsk = 0) : + positions(pos), + weights(w), + boneIndices(bi), + shapeKeyOffsets(sko), + numPos(np), + normals(norm), + vertices(vert), + indices(ind), + numTris(nt), + vertexGroups(vg), + numVertexGroups(nvg), + fullSkeletonName(fsn), + shapeKeys(sk), + numShapeKeys(nsk) + {} }; } diff --git a/model.cpp b/model.cpp index a98cf93..bb5dbd0 100755 --- a/model.cpp +++ b/model.cpp @@ -28,14 +28,14 @@ namespace vb01{ } Model::~Model(){ - delete children[0]->getMesh(0)->getMaterial(); - vector descendants; getDescendants(descendants); for(Node *node : descendants) - for(Mesh *mesh : node->getMeshes()) + for(Mesh *mesh : node->getMeshes()){ + delete mesh->getMaterial(); mesh->setMaterial(nullptr); + } while(!children.empty()){ Node *c = children[children.size() - 1]; diff --git a/quad.cpp b/quad.cpp index 3181479..96adad6 100755 --- a/quad.cpp +++ b/quad.cpp @@ -18,19 +18,22 @@ namespace vb01{ Vector2 subQuadSize = Vector2(size.x / numHorQuads, size.y / numVertQuads); MeshData::Vertex *vertices = new MeshData::Vertex[numVerts]; + Vector3 *faceVertPos = new Vector3[6]; + + Vector3 *norm = new Vector3(Vector3::VEC_J); for(int i = 0; i < numHorQuads; i++){ for(int j = 0; j < numVertQuads; j++){ int id = i * 6 * numHorQuads + j * 6; Vector2 offset = Vector2(subQuadSize.x, subQuadSize.y); - Vector3 faceVertPos[]{ - Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * i), - Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * (i + 1)), - Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * i), - Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * i), - Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * (i + 1)), - Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * (i + 1)) - }; + + faceVertPos[0] = Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * i); + faceVertPos[1] = Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * (i + 1)); + faceVertPos[2] = Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * i); + faceVertPos[3] = Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * i); + faceVertPos[4] = Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * (i + 1)); + faceVertPos[5] = Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * (i + 1)); + Vector2 faceVertUv[]{ Vector2(float(j) / numHorQuads, float(i) / numVertQuads), Vector2(float(j + 1) / numHorQuads, float(i + 1) / numVertQuads), @@ -48,10 +51,10 @@ namespace vb01{ } MeshData::Vertex v; - v.pos = faceVertPos[k]; + v.pos = &faceVertPos[k]; v.uv = faceVertUv[k]; v.tan = Vector3::VEC_I; - v.norm = Vector3::VEC_J; + v.norm = norm; v.biTan = Vector3::VEC_K; vertices[id + k] = v; } @@ -63,6 +66,6 @@ namespace vb01{ for(int i = 0; i < numVerts; i++) indices[i] = i; - meshBase = MeshData(vertices, indices, numTris); + meshBase = MeshData((Vector3*)faceVertPos, nullptr, nullptr, nullptr, 6, nullptr, vertices, indices, numTris); } } diff --git a/rayCaster.cpp b/rayCaster.cpp index 43e09df..dc6f6d2 100644 --- a/rayCaster.cpp +++ b/rayCaster.cpp @@ -42,7 +42,7 @@ namespace vb01{ bool skip = false; for(int j = 0; j < 3; j++){ - Vector3 rayPosToVert = (vertices[i * 3 + j].pos - rayPos); + Vector3 rayPosToVert = (*(vertices[i * 3 + j].pos) - rayPos); float angle = rayDir.getAngleBetween(rayPosToVert.norm()); if(angle > PI / 2) angle = PI - angle; @@ -58,7 +58,7 @@ namespace vb01{ if(skip) continue; } - Vector3 pointA = pos + rot * vertices[indices[i * 3]].pos, pointB = pos + rot * vertices[indices[i * 3 + 1]].pos, pointC = pos + rot * vertices[indices[i * 3 + 2]].pos; + Vector3 pointA = pos + rot * *(vertices[indices[i * 3]].pos), pointB = pos + rot * *(vertices[indices[i * 3 + 1]].pos), pointC = pos + rot * *(vertices[indices[i * 3 + 2]].pos); Vector3 hypVec = pointA - rayPos; Vector3 perpVec = (pointB - pointA).cross(pointC - pointA).norm(); float a1 = hypVec.norm().getAngleBetween(perpVec); diff --git a/xmlModelReader.cpp b/xmlModelReader.cpp index 234c27f..8c2c879 100644 --- a/xmlModelReader.cpp +++ b/xmlModelReader.cpp @@ -59,44 +59,61 @@ namespace vb01{ } } + //TODO remove the 4 literal for bone weights and indices Mesh* XmlModelReader::processMesh(XMLElement *meshEl){ - vector vertPos, vertNorm; - vector weights; + int numVertPos = 0; + vector vp; + vector w; const char *tagName = "vertdata"; - for(XMLElement *vertEl = meshEl->FirstChildElement(tagName); vertEl && strcmp(vertEl->Name(), tagName) == 0; vertEl = vertEl->NextSiblingElement()){ + for(XMLElement *vertEl = meshEl->FirstChildElement(tagName); vertEl && strcmp(vertEl->Name(), tagName) == 0; vertEl = vertEl->NextSiblingElement(), numVertPos++){ float posX = atof(vertEl->Attribute("px")); float posY = atof(vertEl->Attribute("py")); float posZ = atof(vertEl->Attribute("pz")); - vertPos.push_back(Vector3(posX, posY, posZ)); - - float normX = atof(vertEl->Attribute("nx")); - float normY = atof(vertEl->Attribute("ny")); - float normZ = atof(vertEl->Attribute("nz")); - vertNorm.push_back(Vector3(normX, normY, normZ)); + vp.push_back(Vector3(posX, posY, posZ)); for(XMLElement *weightEl = vertEl->FirstChildElement("weight"); weightEl; weightEl = weightEl->NextSiblingElement()) - weights.push_back(atof(weightEl->Attribute("value"))); + w.push_back(atof(weightEl->Attribute("value"))); } int numVertexGroups = atoi(meshEl->Attribute("num_vertex_groups")); + + Vector3 *vertPos = new Vector3[numVertPos]; + float **weights = new float*[numVertPos]; + int **boneIndices = new int*[numVertPos]; + + for(int i = 0; i < vp.size(); i++){ + vertPos[i] = vp[i]; + weights[i] = new float[4]; + boneIndices[i] = new int[4]; + + for(int j = 0; j < 4; j++){ + weights[i][j] = 0; + //weights[i][j] = w[i * numVertexGroups + j]; + boneIndices[i][j] = -1; + } + } + + vp.clear(); + w.clear(); + string *vertexGroups = new string[numVertexGroups]; tagName = "vertexgroup"; int i = 0; for(XMLElement *vertGroupEl = meshEl->FirstChildElement(tagName); vertGroupEl && strcmp(vertGroupEl->Name(), tagName) == 0; vertGroupEl = vertGroupEl->NextSiblingElement(), i++) - vertexGroups[i] = (vertGroupEl->Attribute("name")); + vertexGroups[i] = (vertGroupEl->Attribute("name")); i = 0; int numVertices = 3 * atoi(meshEl->Attribute("num_faces")); MeshData::Vertex *vertices = new MeshData::Vertex[numVertices]; tagName = "vert"; - vector vertIds; u32 *indices = new u32[numVertices]; + Vector3 *normals = new Vector3[numVertices]; + for(XMLElement *vertEl = meshEl->FirstChildElement(tagName); vertEl && strcmp(vertEl->Name(), tagName) == 0; vertEl = vertEl->NextSiblingElement(), i++){ int id = atoi(vertEl->Attribute("id")); - vertIds.push_back(id); float uvX = atof(vertEl->Attribute("uvx")); float uvY = atof(vertEl->Attribute("uvy")); @@ -112,30 +129,39 @@ namespace vb01{ float biTanZ = atof(vertEl->Attribute("bz")); Vector3 biTan = Vector3(biTanX, biTanY, biTanZ); + normals[i] = tan.cross(biTan); + MeshData::Vertex vertex; - vertex.pos = vertPos[id]; - vertex.norm = vertNorm[id]; + vertex.pos = &vertPos[id]; + vertex.norm = &normals[id]; vertex.uv = uv; vertex.tan = tan; vertex.biTan = biTan; for(int j = 0, boneIndex = 0; j < numVertexGroups; j++){ - if(weights[id * numVertexGroups + j] > 0){ - vertex.boneIndices[boneIndex] = j; - vertex.weights[boneIndex] = weights[id * numVertexGroups + j]; + if(weights[id][j] > 0){ + boneIndices[id][boneIndex] = j; + //weights[id][boneIndex] = weights[id * numVertexGroups + j]; boneIndex++; } } + vertex.weights = weights[id]; + vertex.boneIndices = boneIndices[id]; + indices[i] = i; vertices[i] = vertex; } - vertNorm.clear(); tagName = "shapekey"; i = 0; int numShapeKeys = atoi(meshEl->Attribute("num_shape_keys")); MeshData::ShapeKey *shapeKeys = new MeshData::ShapeKey[numShapeKeys]; + Vector3 **shapeKeyOffsets = new Vector3*[numVertPos]; + + for(int i = 0; i < numVertPos; i++){ + shapeKeyOffsets[i] = new Vector3[100]; + } for(XMLElement *shapeKeyEl = meshEl->FirstChildElement(tagName); shapeKeyEl && strcmp(shapeKeyEl->Name(), tagName) == 0; shapeKeyEl = shapeKeyEl->NextSiblingElement(), i++){ string name = shapeKeyEl->Attribute("name"); @@ -159,13 +185,19 @@ namespace vb01{ shapeKeyPos.push_back(Vector3(posX, posY, posZ)); } - for(int j = 0; j < numVertices; j++) - vertices[j].shapeKeyOffsets[i] = shapeKeyPos[vertIds[j]] - vertPos[vertIds[j]]; + /* + for(int j = 0; j < numVertPos; j++){ + shapeKeyOffsets[i] = new Vector3[100]; + + for(int k = 0; k < 100; k++) + shapeKeyOffsets[i][k] = shapeKeyPos[vertIds[j]] - vertPos[vertIds[j]]; + } + */ } const char *fullSkeletonName = meshEl->Attribute("skeleton"); string name = string(meshEl->Parent()->ToElement()->Attribute("name")) + string(meshEl->Attribute("name")); - Mesh *mesh = new Mesh(MeshData(vertices, indices, numVertices / 3, name, vertexGroups, numVertexGroups, (fullSkeletonName ? fullSkeletonName : ""), shapeKeys, numShapeKeys)); + Mesh *mesh = new Mesh(MeshData(vertPos, weights, boneIndices, shapeKeyOffsets, numVertPos, normals, vertices, indices, numVertices / 3, name, vertexGroups, numVertexGroups, (fullSkeletonName ? fullSkeletonName : ""), shapeKeys, numShapeKeys)); return mesh; } @@ -293,7 +325,7 @@ namespace vb01{ XMLElement *meshTag = xmlEl->FirstChildElement("mesh"); if(meshTag) - node->attachMesh(processMesh(meshTag)); + node->attachMesh(processMesh(meshTag)); XMLElement *lightTag = xmlEl->FirstChildElement("light");