diff --git a/browedit/components/Rsm.cpp b/browedit/components/Rsm.cpp index 766e6b5..91e8a75 100644 --- a/browedit/components/Rsm.cpp +++ b/browedit/components/Rsm.cpp @@ -79,7 +79,6 @@ void Rsm::reload() } else if (version >= 0x0202) { - float fps; rsmFile->read(reinterpret_cast(&fps), sizeof(float)); int textureCount; @@ -422,7 +421,7 @@ Rsm::Mesh::Mesh(Rsm* model, std::istream* rsmFile) rsmFile->read(reinterpret_cast(&scaleFrames[i].time), sizeof(int)); rsmFile->read(reinterpret_cast(glm::value_ptr(scaleFrames[i].scale)), sizeof(float) * 3); rsmFile->read(reinterpret_cast(&scaleFrames[i].data), sizeof(float)); - if (model->version > 0x0202) + if (model->version >= 0x0202) scaleFrames[i].time = (int)ceil(scaleFrames[i].time * model->fps); //TODO: remove this } } @@ -440,7 +439,7 @@ Rsm::Mesh::Mesh(Rsm* model, std::istream* rsmFile) rsmFile->read(reinterpret_cast(&z), sizeof(float)); rsmFile->read(reinterpret_cast(&w), sizeof(float)); rotFrames[i].quaternion = glm::quat(w, x, y, z); - if (model->version > 0x0202) + if (model->version >= 0x0202) rotFrames[i].time = (int)ceil(rotFrames[i].time * model->fps); //TODO: remove this } @@ -518,67 +517,193 @@ void Rsm::Mesh::calcMatrix1(int time) { matrix1 = glm::mat4(1.0f); - if (parent == NULL) - { - if (children.size() > 0) - matrix1 = glm::translate(matrix1, glm::vec3(-model->bbrange.x, -model->bbmax.y, -model->bbrange.z)); + if (model->version < 0x0202) { + if (parent == NULL) + { + if (children.size() > 0) + matrix1 = glm::translate(matrix1, glm::vec3(-model->bbrange.x, -model->bbmax.y, -model->bbrange.z)); + else + matrix1 = glm::translate(matrix1, glm::vec3(0, -model->bbmax.y + model->bbrange.y, 0)); + } else - matrix1 = glm::translate(matrix1, glm::vec3(0, -model->bbmax.y + model->bbrange.y, 0)); - } - else - matrix1 = glm::translate(matrix1, pos); + matrix1 = glm::translate(matrix1, pos); - if (rotFrames.size() == 0) - { - if (fabs(rotangle) > 0.01) - matrix1 = glm::rotate(matrix1, glm::radians(rotangle * 180.0f / 3.14159f), rotaxis); //TODO: double conversion - } - else - { - if (rotFrames[rotFrames.size() - 1].time != 0) + if (rotFrames.size() == 0) { - int tick = time % rotFrames[rotFrames.size() - 1].time; - int current = 0; - for (unsigned int i = 0; i < rotFrames.size(); i++) + if (fabs(rotangle) > 0.01) + matrix1 = glm::rotate(matrix1, glm::radians(rotangle * 180.0f / 3.14159f), rotaxis); //TODO: double conversion + } + else + { + if (rotFrames[rotFrames.size() - 1].time != 0) { - if (rotFrames[i].time > tick) + int tick = time % rotFrames[rotFrames.size() - 1].time; + int current = 0; + for (unsigned int i = 0; i < rotFrames.size(); i++) { - current = i - 1; - break; + if (rotFrames[i].time > tick) + { + current = i - 1; + break; + } } - } - if (current < 0) - current = 0; + if (current < 0) + current = 0; - int next = current + 1; - if (next >= (int)rotFrames.size()) - next = 0; + int next = current + 1; + if (next >= (int)rotFrames.size()) + next = 0; - float interval = ((float)(tick - rotFrames[current].time)) / ((float)(rotFrames[next].time - rotFrames[current].time)); + float interval = ((float)(tick - rotFrames[current].time)) / ((float)(rotFrames[next].time - rotFrames[current].time)); #if 1 - glm::quat quat = glm::mix(rotFrames[current].quaternion, rotFrames[next].quaternion, interval); + glm::quat quat = glm::mix(rotFrames[current].quaternion, rotFrames[next].quaternion, interval); #else - bEngine::math::cQuaternion quat( - (1 - interval) * animationFrames[current].quat.x + interval * animationFrames[next].quat.x, - (1 - interval) * animationFrames[current].quat.y + interval * animationFrames[next].quat.y, - (1 - interval) * animationFrames[current].quat.z + interval * animationFrames[next].quat.z, - (1 - interval) * animationFrames[current].quat.w + interval * animationFrames[next].quat.w); + bEngine::math::cQuaternion quat( + (1 - interval) * animationFrames[current].quat.x + interval * animationFrames[next].quat.x, + (1 - interval) * animationFrames[current].quat.y + interval * animationFrames[next].quat.y, + (1 - interval) * animationFrames[current].quat.z + interval * animationFrames[next].quat.z, + (1 - interval) * animationFrames[current].quat.w + interval * animationFrames[next].quat.w); #endif - quat = glm::normalize(quat); + quat = glm::normalize(quat); + + matrix1 = matrix1 * glm::toMat4(quat); + + } + else + { + matrix1 *= glm::toMat4(glm::normalize(rotFrames[0].quaternion)); + } + } + + matrix1 = glm::scale(matrix1, scale); + } + else { + matrix2 = glm::mat4(1.0f); + + if (scaleFrames.size() > 0) { + if (scaleFrames[scaleFrames.size() - 1].time != 0) + { + int tick = model->version >= 0x203 ? time % model->animLen : time % scaleFrames[scaleFrames.size() - 1].time; + + if (tick >= scaleFrames[scaleFrames.size() - 1].time) { + matrix1 = glm::scale(matrix1, scaleFrames[scaleFrames.size() - 1].scale); + } + else { + for (unsigned int i = 0; i < scaleFrames.size() - 1; i++) + { + if (tick >= scaleFrames[i].time && tick < scaleFrames[i + 1].time) + { + float interval = ((float)(tick - scaleFrames[i].time)) / ((float)(scaleFrames[i + 1].time - scaleFrames[i].time)); + glm::vec3 scale = scaleFrames[i].scale + (scaleFrames[i + 1].scale - scaleFrames[i].scale) * interval; + matrix1 = glm::scale(matrix1, scale); + break; + } + } + } + } + else + { + matrix1 = glm::scale(matrix1, scaleFrames[0].scale); + } + } + + if (rotFrames.size() > 0) + { + if (rotFrames[rotFrames.size() - 1].time != 0) + { + int tick = model->version >= 0x203 ? time % model->animLen : time % rotFrames[rotFrames.size() - 1].time; + + if (tick >= rotFrames[rotFrames.size() - 1].time) { + matrix1 = matrix1 * glm::toMat4(rotFrames[rotFrames.size() - 1].quaternion); + } + else { + for (unsigned int i = 0; i < rotFrames.size() - 1; i++) + { + if (tick >= rotFrames[i].time && tick < rotFrames[i + 1].time) + { + float interval = ((float)(tick - rotFrames[i].time)) / ((float)(rotFrames[i + 1].time - rotFrames[i].time)); + glm::quat quat = glm::slerp(rotFrames[i].quaternion, rotFrames[i + 1].quaternion, interval); + matrix1 = glm::toMat4(quat) * matrix1; + break; + } + } + } + } + else + { + matrix1 = glm::toMat4(glm::normalize(rotFrames[0].quaternion)) * matrix1; + } + } + else + { + matrix1 = offset * matrix1; + + if (parent != NULL) + { + matrix1 = glm::inverse(parent->offset) * matrix1; + } + } - matrix1 = matrix1 * glm::toMat4(quat); + matrix2 = glm::mat4(matrix1); + glm::vec3 position; + + if (posFrames.size() > 0) { + if (posFrames[posFrames.size() - 1].time != 0) + { + int tick = model->version >= 0x203 ? time % model->animLen : time % posFrames[posFrames.size() - 1].time; + if (tick >= posFrames[posFrames.size() - 1].time) { + position = posFrames[posFrames.size() - 1].position; + } + else { + for (unsigned int i = 0; i < posFrames.size() - 1; i++) + { + if (tick >= posFrames[i].time && tick < posFrames[i + 1].time) + { + float interval = ((float)(tick - posFrames[i].time)) / ((float)(posFrames[i + 1].time - posFrames[i].time)); + position = posFrames[i].position + (posFrames[i + 1].position - posFrames[i].position) * interval; + break; + } + } + } + } + else + { + position = posFrames[0].position; + } } else { - matrix1 *= glm::toMat4(glm::normalize(rotFrames[0].quaternion)); + if (parent != NULL) + { + position = pos_ - parent->pos_; + position = glm::inverse(parent->offset) * glm::vec4(position.x, position.y, position.z, 0); + } + else { + position = pos_; + } } - } - matrix1 = glm::scale(matrix1, scale); - // if(nAnimationFrames == 0) - // cache1 = true; + matrix2[3].x = position.x; + matrix2[3].y = position.y; + matrix2[3].z = position.z; + + Mesh *mesh = this; + + while (mesh->parent != NULL) + { + mesh = mesh->parent; + matrix2 = mesh->matrix1 * matrix2; + } + + if (parent != NULL) + { + matrix2[3].x += parent->matrix2[3].x; + matrix2[3].y += parent->matrix2[3].y; + matrix2[3].z += parent->matrix2[3].z; + } + } for (unsigned int i = 0; i < children.size(); i++) children[i]->calcMatrix1(time); @@ -588,16 +713,19 @@ void Rsm::Mesh::calcMatrix2() { matrix2 = glm::mat4(1.0f); - if (parent == NULL && children.size() == 0) - matrix2 = glm::translate(matrix2, -1.0f * model->bbrange); + if (model->version < 0x202) { + if (parent == NULL && children.size() == 0) { + matrix2 = glm::translate(matrix2, -1.0f * model->bbrange); + } - if (parent != NULL || children.size() != 0) - matrix2 = glm::translate(matrix2, pos_); + if (parent != NULL || children.size() != 0) + matrix2 = glm::translate(matrix2, pos_); - matrix2 *= offset; + matrix2 *= offset; - for (unsigned int i = 0; i < children.size(); i++) - children[i]->calcMatrix2(); + for (unsigned int i = 0; i < children.size(); i++) + children[i]->calcMatrix2(); + } } diff --git a/browedit/components/RsmRenderer.cpp b/browedit/components/RsmRenderer.cpp index 30c07bf..854632d 100644 --- a/browedit/components/RsmRenderer.cpp +++ b/browedit/components/RsmRenderer.cpp @@ -105,11 +105,12 @@ void RsmRenderer::render() if (rswModel) { matrixCache = glm::scale(matrixCache, glm::vec3(rswObject->scale.x, -rswObject->scale.y, rswObject->scale.z)); - matrixCache = glm::translate(matrixCache, glm::vec3(-rsm->realbbrange.x, rsm->realbbmin.y, -rsm->realbbrange.z)); - if (rsm->version >= 0x0202) - { + + if (rsm->version < 0x0202) { + matrixCache = glm::translate(matrixCache, glm::vec3(-rsm->realbbrange.x, rsm->realbbmin.y, -rsm->realbbrange.z)); + } + else { matrixCache = glm::scale(matrixCache, glm::vec3(1, -1, 1)); - matrixCache = glm::translate(matrixCache, glm::vec3(0, rsm->realbbmax.y, 0)); } } @@ -134,7 +135,6 @@ void RsmRenderer::render() { matrixCache = glm::mat4(1.0f); matrixCache = glm::scale(matrixCache, glm::vec3(1, -1, 1)); - matrixCache = glm::translate(matrixCache, glm::vec3(0, rsm->realbbmax.y, 0)); } auto shader = dynamic_cast(renderContext)->shader; shader->setUniform(RsmShader::Uniforms::shadeType, (int)rsm->shadeType); @@ -196,8 +196,15 @@ void RsmRenderer::initMeshInfo(Rsm::Mesh* mesh, const glm::mat4 &matrix) renderInfo[mesh->index].vbo = new gl::VBO(); renderInfo[mesh->index].vbo->setData(allVerts, GL_STATIC_DRAW); } - renderInfo[mesh->index].matrix = matrix * mesh->matrix1 * mesh->matrix2; - renderInfo[mesh->index].matrixSub = matrix * mesh->matrix1; + + if (mesh->model->version >= 0x202) { + renderInfo[mesh->index].matrix = mesh->matrix2; + renderInfo[mesh->index].matrixSub = glm::mat4(1.0f); + } + else { + renderInfo[mesh->index].matrix = matrix * mesh->matrix1 * mesh->matrix2; + renderInfo[mesh->index].matrixSub = matrix * mesh->matrix1; + } //if (mesh->textureFiles.size() > 0) // 0x0203 // for (auto& textureFilename : mesh->textureFiles) @@ -208,7 +215,7 @@ void RsmRenderer::initMeshInfo(Rsm::Mesh* mesh, const glm::mat4 &matrix) meshDirty = false; } -void RsmRenderer::renderMesh(Rsm::Mesh* mesh, const glm::mat4& matrix, bool selectionPhase) +void RsmRenderer::renderMesh(Rsm::Mesh* mesh, const glm::mat4& matrix, bool selectionPhase, bool calcMatrix) { if (textures.empty()) { @@ -216,15 +223,26 @@ void RsmRenderer::renderMesh(Rsm::Mesh* mesh, const glm::mat4& matrix, bool sele textures.push_back(util::ResourceManager::load("data\\texture\\" + textureFilename)); } - if (mesh && (!mesh->rotFrames.empty() || mesh->matrixDirty)) + if (mesh && (!mesh->rotFrames.empty() || mesh->model->version >= 0x202 || mesh->matrixDirty)) { mesh->matrixDirty = false; - if(time < 0) - mesh->calcMatrix1((int)floor(glfwGetTime() * 1000)); - else - mesh->calcMatrix1((int)floor(time * 1000)); - renderInfo[mesh->index].matrix = matrix * mesh->matrix1 * mesh->matrix2; - renderInfo[mesh->index].matrixSub = matrix * mesh->matrix1; + + if (calcMatrix) { + if(time < 0) + mesh->calcMatrix1((int)floor(glfwGetTime() * 1000)); + else + mesh->calcMatrix1((int)floor(time * 1000)); + } + + if (mesh->model->version >= 0x202) { + calcMatrix = false; + renderInfo[mesh->index].matrix = mesh->matrix2; + renderInfo[mesh->index].matrixSub = glm::mat4(1.0f); + } + else { + renderInfo[mesh->index].matrix = matrix * mesh->matrix1 * mesh->matrix2; + renderInfo[mesh->index].matrixSub = matrix * mesh->matrix1; + } } auto shader = dynamic_cast(renderContext)->shader; diff --git a/browedit/components/RsmRenderer.h b/browedit/components/RsmRenderer.h index 3196ad0..2993125 100644 --- a/browedit/components/RsmRenderer.h +++ b/browedit/components/RsmRenderer.h @@ -76,7 +76,7 @@ class RsmRenderer : public Renderer void begin(); virtual void render(); void initMeshInfo(Rsm::Mesh* mesh, const glm::mat4& matrix = glm::mat4(1.0f)); - void renderMesh(Rsm::Mesh* mesh, const glm::mat4& matrix, bool selectionPhase = false); + void renderMesh(Rsm::Mesh* mesh, const glm::mat4& matrix, bool selectionPhase = false, bool calcMatrix = true); virtual bool shouldRender(int phase) { return phase == 0 ? !selected : selected; }