Skip to content

Commit

Permalink
Merge pull request #9 from Tokeiburu/model-animation-fix
Browse files Browse the repository at this point in the history
Fixed RSM2 animations' behavior and using animSpeed to show the correct animation speed.
  • Loading branch information
Borf committed Nov 30, 2023
2 parents f0f598c + 5c0b0fe commit 3a36903
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 69 deletions.
124 changes: 57 additions & 67 deletions browedit/components/Rsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void Rsm::reload()
else if (version >= 0x0202)
{
rsmFile->read(reinterpret_cast<char*>(&fps), sizeof(float));

animLen = (int)ceil(animLen * fps);
int textureCount;
rsmFile->read(reinterpret_cast<char*>(&textureCount), sizeof(int));;
if (textureCount > 100 || textureCount < 0)
Expand Down Expand Up @@ -582,58 +582,51 @@ void Rsm::Mesh::calcMatrix1(int time)
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);
int tick = time % glm::max(1, model->animLen);
int prevIndex = -1;
int nextIndex = -1;

while (true) {
nextIndex++;

if (nextIndex == scaleFrames.size() || tick < scaleFrames[nextIndex].time)
break;

prevIndex++;
}

float prevTick = prevIndex < 0 ? 0 : scaleFrames[prevIndex].time;
float nextTick = nextIndex == scaleFrames.size() ? model->animLen : scaleFrames[nextIndex].time;
glm::vec3 prev = prevIndex < 0 ? glm::vec3(1) : scaleFrames[prevIndex].scale;
glm::vec3 next = nextIndex == scaleFrames.size() ? scaleFrames[nextIndex - 1].scale : scaleFrames[nextIndex].scale;

float mult = (tick - prevTick) / (nextTick - prevTick);
matrix1 = glm::scale(matrix1, mult * (next - prev) + prev);
}

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;
int tick = time % glm::max(1, model->animLen);
int prevIndex = -1;
int nextIndex = -1;

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;
while (true) {
nextIndex++;

if (nextIndex == rotFrames.size() || tick < rotFrames[nextIndex].time)
break;

prevIndex++;
}

float prevTick = prevIndex < 0 ? 0 : rotFrames[prevIndex].time;
float nextTick = nextIndex == rotFrames.size() ? model->animLen : rotFrames[nextIndex].time;
glm::quat prev = prevIndex < 0 ? glm::quat() : rotFrames[prevIndex].quaternion;
glm::quat next = nextIndex == rotFrames.size() ? rotFrames[nextIndex - 1].quaternion : rotFrames[nextIndex].quaternion;

float mult = (tick - prevTick) / (nextTick - prevTick);
glm::quat quat = glm::slerp(prev, next, mult);
matrix1 = glm::toMat4(quat) * matrix1;
}
else
{
Expand All @@ -649,29 +642,26 @@ void Rsm::Mesh::calcMatrix1(int time)
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;
int tick = time % glm::max(1, model->animLen);
int prevIndex = -1;
int nextIndex = -1;

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;
while (true) {
nextIndex++;

if (nextIndex == posFrames.size() || tick < posFrames[nextIndex].time)
break;

prevIndex++;
}

float prevTick = prevIndex < 0 ? 0 : posFrames[prevIndex].time;
float nextTick = nextIndex == posFrames.size() ? model->animLen : posFrames[nextIndex].time;
glm::vec3 prev = prevIndex < 0 ? pos_ : posFrames[prevIndex].position;
glm::vec3 next = nextIndex == posFrames.size() ? posFrames[nextIndex - 1].position : posFrames[nextIndex].position;

float mult = (tick - prevTick) / (nextTick - prevTick);
position = mult * (next - prev) + prev;
}
else
{
Expand Down
6 changes: 4 additions & 2 deletions browedit/components/RsmRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,12 @@ void RsmRenderer::renderMesh(Rsm::Mesh* mesh, const glm::mat4& matrix, bool sele
mesh->matrixDirty = false;

if (calcMatrix) {
float mult = this->rswModel != nullptr ? this->rswModel->animSpeed : 1.0f;

if(time < 0)
mesh->calcMatrix1((int)floor(glfwGetTime() * 1000));
mesh->calcMatrix1((int)floor(glfwGetTime() * 1000 * mult));
else
mesh->calcMatrix1((int)floor(time * 1000));
mesh->calcMatrix1((int)floor(time * 1000 * mult));
}

if (mesh->model->version >= 0x202) {
Expand Down

0 comments on commit 3a36903

Please sign in to comment.