diff --git a/BoneAnimatedModel.cpp b/BoneAnimatedModel.cpp new file mode 100644 index 0000000..438c34d --- /dev/null +++ b/BoneAnimatedModel.cpp @@ -0,0 +1,519 @@ +#include "BoneAnimatedModel.h" +#include +#include +#include +#include + +namespace ZL +{ + + int getIndexByValue(const std::string& name, const std::vector& words) + { + for (int i = 0; i < words.size(); i++) + { + if (words[i] == name) + { + return i; + } + } + + return -1; + } + + + void BoneSystem::LoadFromFile(const std::string& fileName) + { + + + std::ifstream f(fileName); + + //Skip first 5 lines + std::string tempLine; + for (int i = 0; i < 5; i++) + { + std::getline(f, tempLine); + } + std::getline(f, tempLine); + + static const std::regex pattern_count(R"(\d+)"); + static const std::regex pattern_float(R"([-]?\d+\.\d+)"); + static const std::regex pattern_int(R"([-]?\d+)"); + static const std::regex pattern_boneChildren(R"(\'([^\']+)\')"); + static const std::regex pattern_bone_weight(R"(\'([^\']+)\'.*?([-]?\d+\.\d+))"); + std::smatch match; + + int numberBones; + + if (std::regex_search(tempLine, match, pattern_count)) { + std::string number_str = match.str(); + numberBones = std::stoi(number_str); + } + else { + throw std::runtime_error("No number found in the input string."); + } + + std::vector bones; + std::vector boneNames; + std::vector boneParentNames; + std::unordered_map> boneChildren; + + bones.resize(numberBones); + boneNames.resize(numberBones); + boneParentNames.resize(numberBones); + + for (int i = 0; i < numberBones; i++) + { + std::getline(f, tempLine); + std::string boneName = tempLine.substr(6); + + boneNames[i] = boneName; + + std::getline(f, tempLine); + + std::vector floatValues; + + auto b = tempLine.cbegin(); + auto e = tempLine.cend(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + bones[i].boneStartWorld = Vector3f{ floatValues[0], floatValues[1], floatValues[2] }; + + + std::getline(f, tempLine); //skip tail + + std::getline(f, tempLine); //len + + if (std::regex_search(tempLine, match, pattern_float)) { + std::string len_str = match.str(); + bones[i].boneLength = std::stof(len_str); + } + else { + throw std::runtime_error("No number found in the input string."); + } + //---------- matrix begin + + std::getline(f, tempLine); + + b = tempLine.cbegin(); + e = tempLine.cend(); + floatValues.clear(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + bones[i].boneMatrixWorld.m[0] = floatValues[0]; + bones[i].boneMatrixWorld.m[0 + 1 * 3] = floatValues[1]; + bones[i].boneMatrixWorld.m[0 + 2 * 3] = floatValues[2]; + + + std::getline(f, tempLine); + + b = tempLine.cbegin(); + e = tempLine.cend(); + floatValues.clear(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + bones[i].boneMatrixWorld.m[1] = floatValues[0]; + bones[i].boneMatrixWorld.m[1 + 1 * 3] = floatValues[1]; + bones[i].boneMatrixWorld.m[1 + 2 * 3] = floatValues[2]; + + + std::getline(f, tempLine); + + b = tempLine.cbegin(); + e = tempLine.cend(); + floatValues.clear(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + bones[i].boneMatrixWorld.m[2] = floatValues[0]; + bones[i].boneMatrixWorld.m[2 + 1 * 3] = floatValues[1]; + bones[i].boneMatrixWorld.m[2 + 2 * 3] = floatValues[2]; + + //----------- matrix end + std::getline(f, tempLine); //parent + + if (tempLine == " Parent: None") + { + bones[i].parent = -1; + } + else + { + std::string boneParent = tempLine.substr(10); + boneParentNames[i] = boneParent; + } + + std::getline(f, tempLine); //children + + b = tempLine.cbegin(); + e = tempLine.cend(); + while (std::regex_search(b, e, match, pattern_boneChildren)) { + + boneChildren[boneName].push_back(match.str(1)); + b = match.suffix().first; + } + + } + + //Now process all the bones: + for (int i = 0; i < numberBones; i++) + { + std::string boneName = boneNames[i]; + std::string boneParent = boneParentNames[i]; + if (boneParent == "") + { + bones[i].parent = -1; + } + else + { + bones[i].parent = getIndexByValue(boneParent, boneNames); + } + + for (int j = 0; j < boneChildren[boneName].size(); j++) + { + bones[i].children.push_back(getIndexByValue(boneChildren[boneName][j], boneNames)); + } + } + + startBones = bones; + currentBones = bones; + + ///std::cout << "Hello!" << std::endl; + + std::getline(f, tempLine); //vertice count + int numberVertices; + + if (std::regex_search(tempLine, match, pattern_count)) { + std::string number_str = match.str(); + numberVertices = std::stoi(number_str); + } + else { + throw std::runtime_error("No number found in the input string."); + } + + std::vector vertices; + + vertices.resize(numberVertices); + for (int i = 0; i < numberVertices; i++) + { + std::getline(f, tempLine); + + std::vector floatValues; + + auto b = tempLine.cbegin(); + auto e = tempLine.cend(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + vertices[i] = Vector3f{floatValues[0], floatValues[1], floatValues[2]}; + } + + std::getline(f, tempLine); //vertice count + int numberTriangles; + + if (std::regex_search(tempLine, match, pattern_count)) { + std::string number_str = match.str(); + numberTriangles = std::stoi(number_str); + } + else { + throw std::runtime_error("No number found in the input string."); + } + + std::vector> triangles; + + triangles.resize(numberTriangles); + for (int i = 0; i < numberTriangles; i++) + { + std::getline(f, tempLine); + + std::vector intValues; + + auto b = tempLine.cbegin(); + auto e = tempLine.cend(); + while (std::regex_search(b, e, match, pattern_int)) { + intValues.push_back(std::stoi(match.str())); + b = match.suffix().first; + } + + triangles[i] = { intValues[0], intValues[1], intValues[2] }; + } + + std::getline(f, tempLine);//=== Vertex Weights === + std::vector> localVerticesBoneWeight; + localVerticesBoneWeight.resize(numberVertices); + + for (int i = 0; i < numberVertices; i++) + { + std::getline(f, tempLine); //skip Vertex 0: + std::getline(f, tempLine); //vertex group count + int boneCount; + + if (std::regex_search(tempLine, match, pattern_count)) { + std::string number_str = match.str(); + boneCount = std::stoi(number_str); + } + else { + throw std::runtime_error("No number found in the input string."); + } + + if (boneCount > 3) + { + throw std::runtime_error("more than 3 bones"); + } + + float sumWeights = 0; + + for (int j = 0; j < boneCount; j++) + { + std::getline(f, tempLine); //Group: 'Bone', Weight: 0.9929084181785583 + if (std::regex_search(tempLine, match, pattern_bone_weight)) { + // Извлекаем слово (без кавычек) + std::string word = match.str(1); + double weight = std::stod(match.str(2)); + + int boneNumber = getIndexByValue(word, boneNames); + localVerticesBoneWeight[i][j].boneIndex = boneNumber; + localVerticesBoneWeight[i][j].weight = weight; + sumWeights += weight; + } + else { + throw std::runtime_error("No match found in the input string."); + } + } + + //Normalize weights: + for (int j = 0; j < boneCount; j++) + { + localVerticesBoneWeight[i][j].weight = localVerticesBoneWeight[i][j].weight / sumWeights; + } + + + + } + + std::getline(f, tempLine);//=== Animation Keyframes === + std::getline(f, tempLine);//=== Bone Transforms per Keyframe === + + + + std::getline(f, tempLine); + int numberKeyFrames; + + if (std::regex_search(tempLine, match, pattern_count)) { + std::string number_str = match.str(); + numberKeyFrames = std::stoi(number_str); + } + else { + throw std::runtime_error("No number found in the input string."); + } + + animations.resize(1); + + animations[0].keyFrames.resize(numberKeyFrames); + + for (int i = 0; i < numberKeyFrames; i++) + { + std::getline(f, tempLine); + int numberFrame; + + if (std::regex_search(tempLine, match, pattern_count)) { + std::string number_str = match.str(); + numberFrame = std::stoi(number_str); + } + else { + throw std::runtime_error("No number found in the input string."); + } + + animations[0].keyFrames[i].frame = numberFrame; + + animations[0].keyFrames[i].bones.resize(numberBones); + + for (int j = 0; j < numberBones; j++) + { + std::getline(f, tempLine); + std::string boneName = tempLine.substr(8); + int boneNumber = getIndexByValue(boneName, boneNames); + animations[0].keyFrames[i].bones[boneNumber] = startBones[boneNumber]; + + std::getline(f, tempLine); // Location: + + std::vector floatValues; + + auto b = tempLine.cbegin(); + auto e = tempLine.cend(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + animations[0].keyFrames[i].bones[boneNumber].boneStartWorld = Vector3f{ floatValues[0], floatValues[1], floatValues[2] }; + + std::getline(f, tempLine); // Rotation + std::getline(f, tempLine); // Matrix + + //=============== Matrix begin ================== + std::getline(f, tempLine); + + + b = tempLine.cbegin(); + e = tempLine.cend(); + floatValues.clear(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0] = floatValues[0]; + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0 + 1 * 3] = floatValues[1]; + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0 + 2 * 3] = floatValues[2]; + + + std::getline(f, tempLine); + b = tempLine.cbegin(); + e = tempLine.cend(); + floatValues.clear(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1] = floatValues[0]; + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1 + 1 * 3] = floatValues[1]; + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1 + 2 * 3] = floatValues[2]; + + std::getline(f, tempLine); + b = tempLine.cbegin(); + e = tempLine.cend(); + floatValues.clear(); + while (std::regex_search(b, e, match, pattern_float)) { + floatValues.push_back(std::stof(match.str())); + b = match.suffix().first; + } + + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2] = floatValues[0]; + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2 + 1 * 3] = floatValues[1]; + animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2 + 2 * 3] = floatValues[2]; + + + std::getline(f, tempLine);// ignore last matrix line + + //=============== Matrix end ================== + + } + + } + + // Now let's process bone weights and vertices + + for (int i = 0; i < numberTriangles; i++) + { + + mesh.PositionData.push_back(vertices[triangles[i][0]]); + mesh.PositionData.push_back(vertices[triangles[i][1]]); + mesh.PositionData.push_back(vertices[triangles[i][2]]); + + verticesBoneWeight.push_back(localVerticesBoneWeight[triangles[i][0]]); + verticesBoneWeight.push_back(localVerticesBoneWeight[triangles[i][1]]); + verticesBoneWeight.push_back(localVerticesBoneWeight[triangles[i][2]]); + } + + startMesh = mesh; + } + + void BoneSystem::Interpolate(int frame) + { + int startingFrame = -1; + for (int i = 0; i < animations[0].keyFrames.size() - 1; i++) + { + int oldFrame = animations[0].keyFrames[i].frame; + int nextFrame = animations[0].keyFrames[i + 1].frame; + if (frame >= oldFrame && frame < nextFrame) + { + startingFrame = i; + break; + } + } + + if (startingFrame == -1) + { + throw std::runtime_error("Exception here"); + } + + int modifiedFrameNumber = frame - animations[0].keyFrames[startingFrame].frame; + + int diffFrames = animations[0].keyFrames[startingFrame + 1].frame - animations[0].keyFrames[startingFrame].frame; + + float t = (modifiedFrameNumber + 0.f) / diffFrames; + + std::vector& oneFrameBones = animations[0].keyFrames[startingFrame].bones; + std::vector& nextFrameBones = animations[0].keyFrames[startingFrame+1].bones; + + std::vector skinningMatrixForEachBone; + //std::vector skinningMatrixForEachBone; + skinningMatrixForEachBone.resize(currentBones.size()); + + for (int i = 0; i < currentBones.size(); i++) + { + currentBones[i].boneStartWorld.v[0] = oneFrameBones[i].boneStartWorld.v[0] + t * (nextFrameBones[i].boneStartWorld.v[0] - oneFrameBones[i].boneStartWorld.v[0]); + currentBones[i].boneStartWorld.v[1] = oneFrameBones[i].boneStartWorld.v[1] + t * (nextFrameBones[i].boneStartWorld.v[1] - oneFrameBones[i].boneStartWorld.v[1]); + currentBones[i].boneStartWorld.v[2] = oneFrameBones[i].boneStartWorld.v[2] + t * (nextFrameBones[i].boneStartWorld.v[2] - oneFrameBones[i].boneStartWorld.v[2]); + + Vector4f q1 = MatrixToQuat(oneFrameBones[i].boneMatrixWorld); + Vector4f q2 = MatrixToQuat(nextFrameBones[i].boneMatrixWorld); + + Vector4f result = slerp(q1, q2, t); + + currentBones[i].boneMatrixWorld = QuatToMatrix(result); + + //skinningMatrixForEachBone[i] = MultMatrixMatrix(currentBones[i].boneMatrixWorld, InverseMatrix(animations[0].keyFrames[0].bones[i].boneMatrixWorld)); + + Matrix4f currentBoneMatrixWorld4 = MakeMatrix4x4(currentBones[i].boneMatrixWorld, currentBones[i].boneStartWorld); + Matrix4f startBoneMatrixWorld4 = MakeMatrix4x4(animations[0].keyFrames[0].bones[i].boneMatrixWorld, animations[0].keyFrames[0].bones[i].boneStartWorld); + Matrix4f inverstedStartBoneMatrixWorld4 = InverseMatrix(startBoneMatrixWorld4); + + skinningMatrixForEachBone[i] = MultMatrixMatrix(currentBoneMatrixWorld4, inverstedStartBoneMatrixWorld4); + + } + + for (int i = 0; i < mesh.PositionData.size(); i++) + { + Vector4f originalPos = { + startMesh.PositionData[i].v[0], + startMesh.PositionData[i].v[1], + startMesh.PositionData[i].v[2], 1.0}; + + Vector4f finalPos = Vector4f{0.f, 0.f, 0.f, 0.f}; + //Vector3f finalPos = Vector3f{ 0.f, 0.f, 0.f }; + + for (int j = 0; j < 3; j++) + { + if (verticesBoneWeight[i][j].weight != 0) + { + //finalPos = finalPos + MultVectorMatrix(originalPos, skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex]) * verticesBoneWeight[i][j].weight; + finalPos = finalPos + MultMatrixVector(skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex], originalPos) * verticesBoneWeight[i][j].weight; + } + } + + mesh.PositionData[i].v[0] = finalPos.v[0]; + mesh.PositionData[i].v[1] = finalPos.v[1]; + mesh.PositionData[i].v[2] = finalPos.v[2]; + } + + + + + } + + +} \ No newline at end of file diff --git a/BoneAnimatedModel.h b/BoneAnimatedModel.h new file mode 100644 index 0000000..d97734c --- /dev/null +++ b/BoneAnimatedModel.h @@ -0,0 +1,57 @@ +#pragma once +#include "Math.h" +#include "Renderer.h" +#include + + +namespace ZL +{ + struct Bone + { + Vector3f boneStartWorld; + float boneLength; + Matrix3f boneMatrixWorld; + // boneVector = boneLength * (0, 1, 0) в осях блендера + // Then multiply by boneMatrixWorld и вы получите конечную точку + + int parent; + std::vector children; + }; + + struct BoneWeight + { + int boneIndex = -1; + float weight = 0; + }; + + struct AnimationKeyFrame + { + int frame; + std::vector bones; + }; + + struct Animation + { + std::vector keyFrames; + }; + + struct BoneSystem + { + VertexDataStruct mesh; + VertexDataStruct startMesh; + std::vector> verticesBoneWeight; + + std::vector startBones; + std::vector currentBones; + + std::vector animations; + + void LoadFromFile(const std::string& fileName); + + void Interpolate(int frame); + }; + + + + +}; \ No newline at end of file diff --git a/Game.cpp b/Game.cpp index 9eef650..fc1612d 100755 --- a/Game.cpp +++ b/Game.cpp @@ -1,5 +1,7 @@ #include "Game.h" #include "AnimatedModel.h" +#include "BoneAnimatedModel.h" + namespace ZL { @@ -46,6 +48,9 @@ namespace ZL ZL::AnimatedModel testmd3; //std::vector testmd3mutable; + BoneSystem bx; + VertexRenderStruct bxMutable; + } diff --git a/Game.h b/Game.h index 1034085..28d087f 100755 --- a/Game.h +++ b/Game.h @@ -5,6 +5,7 @@ #include "TextureManager.h" #include "Renderer.h" #include "AnimatedModel.h" +#include "BoneAnimatedModel.h" #include namespace ZL @@ -118,5 +119,8 @@ namespace ZL extern ZL::AnimatedModel testmd3; //extern std::vector testmd3; //extern std::vector testmd3mutable; + + extern BoneSystem bx; + extern VertexRenderStruct bxMutable; } } \ No newline at end of file diff --git a/Math.cpp b/Math.cpp index 0a23fa3..fc48a7b 100755 --- a/Math.cpp +++ b/Math.cpp @@ -1,6 +1,7 @@ #include "Math.h" #include +#include namespace ZL { @@ -24,6 +25,48 @@ namespace ZL { return result; } + Vector3f operator+(const Vector3f& x, const Vector3f& y) + { + Vector3f result; + + result.v[0] = x.v[0] + y.v[0]; + result.v[1] = x.v[1] + y.v[1]; + result.v[2] = x.v[2] + y.v[2]; + return result; + } + + Vector3f operator-(const Vector3f& x, const Vector3f& y) + { + Vector3f result; + + result.v[0] = x.v[0] - y.v[0]; + result.v[1] = x.v[1] - y.v[1]; + result.v[2] = x.v[2] - y.v[2]; + return result; + } + + Vector4f operator+(const Vector4f& x, const Vector4f& y) + { + Vector4f result; + + result.v[0] = x.v[0] + y.v[0]; + result.v[1] = x.v[1] + y.v[1]; + result.v[2] = x.v[2] + y.v[2]; + result.v[3] = x.v[3] + y.v[3]; + return result; + } + + Vector4f operator-(const Vector4f& x, const Vector4f& y) + { + Vector4f result; + + result.v[0] = x.v[0] - y.v[0]; + result.v[1] = x.v[1] - y.v[1]; + result.v[2] = x.v[2] - y.v[2]; + result.v[3] = x.v[3] - y.v[3]; + return result; + } + Matrix3f Matrix3f::Identity() { Matrix3f r; @@ -201,6 +244,73 @@ namespace ZL { } + Vector4f MatrixToQuat(const Matrix3f& m) + { + Vector4f r; + float f; + + + if (m.m[0] >= m.m[4] && m.m[0] >= m.m[8]) + { + f = sqrtf(1.0 + m.m[0] - m.m[4] - m.m[8]); + if (f != 0) + { + r.v[3] = (m.m[5] - m.m[7]) / (f + f); + r.v[0] = f / 2; + r.v[1] = (m.m[3] + m.m[1]) / (f + f); + r.v[2] = (m.m[6] + m.m[2]) / (f + f); + } + else + { + r.v[3] = 1; + r.v[2] = 0; + r.v[1] = 0; + r.v[0] = 0; + } + } + + if (m.m[4] >= m.m[0] && m.m[4] >= m.m[8]) + { + f = sqrtf(1 + m.m[4] - m.m[0] - m.m[8]); + if (f != 0) + { + r.v[3] = (m.m[6] - m.m[2]) / (f + f); + r.v[1] = f / 2; + r.v[0] = (m.m[1] + m.m[3]) / (f + f); + r.v[2] = (m.m[7] + m.m[5]) / (f + f); + } + else + { + r.v[3] = 1; + r.v[2] = 0; + r.v[1] = 0; + r.v[0] = 0; + } + } + + if (m.m[8] >= m.m[4] && m.m[8] >= m.m[0]) + { + f = sqrtf(1 + m.m[8] - m.m[2]); + if (f != 0) + { + r.v[3] = (m.m[1] - m.m[3]) / (f + f); + r.v[2] = f / 2; + r.v[1] = (m.m[5] + m.m[7]) / (f + f); + r.v[0] = (m.m[6] + m.m[2]) / (f + f); + } + else + { + r.v[3] = 1; + r.v[2] = 0; + r.v[1] = 0; + r.v[0] = 0; + } + } + + return r; + + } + Vector4f QuatFromRotateAroundX(float angle) { Vector4f result; @@ -285,6 +395,142 @@ namespace ZL { return r; } + + Matrix4f InverseMatrix(const Matrix4f& mat) + { + Matrix4f inv; + float det; + + inv.m[0] = mat.m[5] * mat.m[10] * mat.m[15] - + mat.m[5] * mat.m[11] * mat.m[14] - + mat.m[9] * mat.m[6] * mat.m[15] + + mat.m[9] * mat.m[7] * mat.m[14] + + mat.m[13] * mat.m[6] * mat.m[11] - + mat.m[13] * mat.m[7] * mat.m[10]; + + inv.m[4] = -mat.m[4] * mat.m[10] * mat.m[15] + + mat.m[4] * mat.m[11] * mat.m[14] + + mat.m[8] * mat.m[6] * mat.m[15] - + mat.m[8] * mat.m[7] * mat.m[14] - + mat.m[12] * mat.m[6] * mat.m[11] + + mat.m[12] * mat.m[7] * mat.m[10]; + + inv.m[8] = mat.m[4] * mat.m[9] * mat.m[15] - + mat.m[4] * mat.m[11] * mat.m[13] - + mat.m[8] * mat.m[5] * mat.m[15] + + mat.m[8] * mat.m[7] * mat.m[13] + + mat.m[12] * mat.m[5] * mat.m[11] - + mat.m[12] * mat.m[7] * mat.m[9]; + + inv.m[12] = -mat.m[4] * mat.m[9] * mat.m[14] + + mat.m[4] * mat.m[10] * mat.m[13] + + mat.m[8] * mat.m[5] * mat.m[14] - + mat.m[8] * mat.m[6] * mat.m[13] - + mat.m[12] * mat.m[5] * mat.m[10] + + mat.m[12] * mat.m[6] * mat.m[9]; + + inv.m[1] = -mat.m[1] * mat.m[10] * mat.m[15] + + mat.m[1] * mat.m[11] * mat.m[14] + + mat.m[9] * mat.m[2] * mat.m[15] - + mat.m[9] * mat.m[3] * mat.m[14] - + mat.m[13] * mat.m[2] * mat.m[11] + + mat.m[13] * mat.m[3] * mat.m[10]; + + inv.m[5] = mat.m[0] * mat.m[10] * mat.m[15] - + mat.m[0] * mat.m[11] * mat.m[14] - + mat.m[8] * mat.m[2] * mat.m[15] + + mat.m[8] * mat.m[3] * mat.m[14] + + mat.m[12] * mat.m[2] * mat.m[11] - + mat.m[12] * mat.m[3] * mat.m[10]; + + inv.m[9] = -mat.m[0] * mat.m[9] * mat.m[15] + + mat.m[0] * mat.m[11] * mat.m[13] + + mat.m[8] * mat.m[1] * mat.m[15] - + mat.m[8] * mat.m[3] * mat.m[13] - + mat.m[12] * mat.m[1] * mat.m[11] + + mat.m[12] * mat.m[3] * mat.m[9]; + + inv.m[13] = mat.m[0] * mat.m[9] * mat.m[14] - + mat.m[0] * mat.m[10] * mat.m[13] - + mat.m[8] * mat.m[1] * mat.m[14] + + mat.m[8] * mat.m[2] * mat.m[13] + + mat.m[12] * mat.m[1] * mat.m[10] - + mat.m[12] * mat.m[2] * mat.m[9]; + + inv.m[2] = mat.m[1] * mat.m[6] * mat.m[15] - + mat.m[1] * mat.m[7] * mat.m[14] - + mat.m[5] * mat.m[2] * mat.m[15] + + mat.m[5] * mat.m[3] * mat.m[14] + + mat.m[13] * mat.m[2] * mat.m[7] - + mat.m[13] * mat.m[3] * mat.m[6]; + + inv.m[6] = -mat.m[0] * mat.m[6] * mat.m[15] + + mat.m[0] * mat.m[7] * mat.m[14] + + mat.m[4] * mat.m[2] * mat.m[15] - + mat.m[4] * mat.m[3] * mat.m[14] - + mat.m[12] * mat.m[2] * mat.m[7] + + mat.m[12] * mat.m[3] * mat.m[6]; + + inv.m[10] = mat.m[0] * mat.m[5] * mat.m[15] - + mat.m[0] * mat.m[7] * mat.m[13] - + mat.m[4] * mat.m[1] * mat.m[15] + + mat.m[4] * mat.m[3] * mat.m[13] + + mat.m[12] * mat.m[1] * mat.m[7] - + mat.m[12] * mat.m[3] * mat.m[5]; + + inv.m[14] = -mat.m[0] * mat.m[5] * mat.m[14] + + mat.m[0] * mat.m[6] * mat.m[13] + + mat.m[4] * mat.m[1] * mat.m[14] - + mat.m[4] * mat.m[2] * mat.m[13] - + mat.m[12] * mat.m[1] * mat.m[6] + + mat.m[12] * mat.m[2] * mat.m[5]; + + inv.m[3] = -mat.m[1] * mat.m[6] * mat.m[11] + + mat.m[1] * mat.m[7] * mat.m[10] + + mat.m[5] * mat.m[2] * mat.m[11] - + mat.m[5] * mat.m[3] * mat.m[10] - + mat.m[9] * mat.m[2] * mat.m[7] + + mat.m[9] * mat.m[3] * mat.m[6]; + + inv.m[7] = mat.m[0] * mat.m[6] * mat.m[11] - + mat.m[0] * mat.m[7] * mat.m[10] - + mat.m[4] * mat.m[2] * mat.m[11] + + mat.m[4] * mat.m[3] * mat.m[10] + + mat.m[8] * mat.m[2] * mat.m[7] - + mat.m[8] * mat.m[3] * mat.m[6]; + + inv.m[11] = -mat.m[0] * mat.m[5] * mat.m[11] + + mat.m[0] * mat.m[7] * mat.m[9] + + mat.m[4] * mat.m[1] * mat.m[11] - + mat.m[4] * mat.m[3] * mat.m[9] - + mat.m[8] * mat.m[1] * mat.m[7] + + mat.m[8] * mat.m[3] * mat.m[5]; + + inv.m[15] = mat.m[0] * mat.m[5] * mat.m[10] - + mat.m[0] * mat.m[6] * mat.m[9] - + mat.m[4] * mat.m[1] * mat.m[10] + + mat.m[4] * mat.m[2] * mat.m[9] + + mat.m[8] * mat.m[1] * mat.m[6] - + mat.m[8] * mat.m[2] * mat.m[5]; + + // Вычисляем детерминант + det = mat.m[0] * inv.m[0] + mat.m[1] * inv.m[4] + mat.m[2] * inv.m[8] + mat.m[3] * inv.m[12]; + + if (std::fabs(det) < 0.01f) + { + throw std::runtime_error("Error: matrix cannot be inversed!"); + } + + // Делим все элементы на детерминант + det = 1.0f / det; + for (int i = 0; i < 16; i++) + { + inv.m[i] *= det; + } + + return inv; + } + Matrix3f CreateZRotationMatrix(float angle) { Matrix3f result = Matrix3f::Identity(); @@ -299,28 +545,47 @@ namespace ZL { Matrix4f MultMatrixMatrix(const Matrix4f& m1, const Matrix4f& m2) { - Matrix4f r; + Matrix4f rx; - r.m[0] = m1.m[0] * m2.m[0] + m1.m[4] * m2.m[1] + m1.m[8] * m2.m[2] + m1.m[12] * m2.m[3]; - r.m[1] = m1.m[1] * m2.m[0] + m1.m[5] * m2.m[1] + m1.m[9] * m2.m[2] + m1.m[13] * m2.m[3]; - r.m[2] = m1.m[2] * m2.m[0] + m1.m[6] * m2.m[1] + m1.m[10] * m2.m[2] + m1.m[14] * m2.m[3]; - r.m[3] = m1.m[3] * m2.m[0] + m1.m[7] * m2.m[1] + m1.m[11] * m2.m[2] + m1.m[15] * m2.m[3]; + rx.m[0] = m1.m[0] * m2.m[0] + m1.m[4] * m2.m[1] + m1.m[8] * m2.m[2] + m1.m[12] * m2.m[3]; + rx.m[1] = m1.m[1] * m2.m[0] + m1.m[5] * m2.m[1] + m1.m[9] * m2.m[2] + m1.m[13] * m2.m[3]; + rx.m[2] = m1.m[2] * m2.m[0] + m1.m[6] * m2.m[1] + m1.m[10] * m2.m[2] + m1.m[14] * m2.m[3]; + rx.m[3] = m1.m[3] * m2.m[0] + m1.m[7] * m2.m[1] + m1.m[11] * m2.m[2] + m1.m[15] * m2.m[3]; - r.m[4] = m1.m[0] * m2.m[4] + m1.m[4] * m2.m[5] + m1.m[8] * m2.m[6] + m1.m[12] * m2.m[7]; - r.m[5] = m1.m[1] * m2.m[4] + m1.m[5] * m2.m[5] + m1.m[9] * m2.m[6] + m1.m[13] * m2.m[7]; - r.m[6] = m1.m[2] * m2.m[4] + m1.m[6] * m2.m[5] + m1.m[10] * m2.m[6] + m1.m[14] * m2.m[7]; - r.m[7] = m1.m[3] * m2.m[4] + m1.m[7] * m2.m[5] + m1.m[11] * m2.m[6] + m1.m[15] * m2.m[7]; + rx.m[4] = m1.m[0] * m2.m[4] + m1.m[4] * m2.m[5] + m1.m[8] * m2.m[6] + m1.m[12] * m2.m[7]; + rx.m[5] = m1.m[1] * m2.m[4] + m1.m[5] * m2.m[5] + m1.m[9] * m2.m[6] + m1.m[13] * m2.m[7]; + rx.m[6] = m1.m[2] * m2.m[4] + m1.m[6] * m2.m[5] + m1.m[10] * m2.m[6] + m1.m[14] * m2.m[7]; + rx.m[7] = m1.m[3] * m2.m[4] + m1.m[7] * m2.m[5] + m1.m[11] * m2.m[6] + m1.m[15] * m2.m[7]; - r.m[8] = m1.m[0] * m2.m[8] + m1.m[4] * m2.m[9] + m1.m[8] * m2.m[10] + m1.m[12] * m2.m[11]; - r.m[9] = m1.m[1] * m2.m[8] + m1.m[5] * m2.m[9] + m1.m[9] * m2.m[10] + m1.m[13] * m2.m[11]; - r.m[10] = m1.m[2] * m2.m[8] + m1.m[6] * m2.m[9] + m1.m[10] * m2.m[10] + m1.m[14] * m2.m[11]; - r.m[11] = m1.m[3] * m2.m[8] + m1.m[7] * m2.m[9] + m1.m[11] * m2.m[10] + m1.m[15] * m2.m[11]; + rx.m[8] = m1.m[0] * m2.m[8] + m1.m[4] * m2.m[9] + m1.m[8] * m2.m[10] + m1.m[12] * m2.m[11]; + rx.m[9] = m1.m[1] * m2.m[8] + m1.m[5] * m2.m[9] + m1.m[9] * m2.m[10] + m1.m[13] * m2.m[11]; + rx.m[10] = m1.m[2] * m2.m[8] + m1.m[6] * m2.m[9] + m1.m[10] * m2.m[10] + m1.m[14] * m2.m[11]; + rx.m[11] = m1.m[3] * m2.m[8] + m1.m[7] * m2.m[9] + m1.m[11] * m2.m[10] + m1.m[15] * m2.m[11]; - r.m[12] = m1.m[0] * m2.m[12] + m1.m[4] * m2.m[13] + m1.m[8] * m2.m[14] + m1.m[12] * m2.m[15]; - r.m[13] = m1.m[1] * m2.m[12] + m1.m[5] * m2.m[13] + m1.m[9] * m2.m[14] + m1.m[13] * m2.m[15]; - r.m[14] = m1.m[2] * m2.m[12] + m1.m[6] * m2.m[13] + m1.m[10] * m2.m[14] + m1.m[14] * m2.m[15]; - r.m[15] = m1.m[3] * m2.m[12] + m1.m[7] * m2.m[13] + m1.m[11] * m2.m[14] + m1.m[15] * m2.m[15]; + rx.m[12] = m1.m[0] * m2.m[12] + m1.m[4] * m2.m[13] + m1.m[8] * m2.m[14] + m1.m[12] * m2.m[15]; + rx.m[13] = m1.m[1] * m2.m[12] + m1.m[5] * m2.m[13] + m1.m[9] * m2.m[14] + m1.m[13] * m2.m[15]; + rx.m[14] = m1.m[2] * m2.m[12] + m1.m[6] * m2.m[13] + m1.m[10] * m2.m[14] + m1.m[14] * m2.m[15]; + rx.m[15] = m1.m[3] * m2.m[12] + m1.m[7] * m2.m[13] + m1.m[11] * m2.m[14] + m1.m[15] * m2.m[15]; + + return rx; + } + + Matrix3f MultMatrixMatrix(const Matrix3f& m1, const Matrix3f& m2) + { + Matrix3f r; + + r.m[0] = m1.m[0] * m2.m[0] + m1.m[3] * m2.m[1] + m1.m[6] * m2.m[2]; + r.m[1] = m1.m[1] * m2.m[0] + m1.m[4] * m2.m[1] + m1.m[7] * m2.m[2]; + r.m[2] = m1.m[2] * m2.m[0] + m1.m[5] * m2.m[1] + m1.m[8] * m2.m[2]; + + r.m[3] = m1.m[0] * m2.m[3] + m1.m[3] * m2.m[4] + m1.m[6] * m2.m[5]; + r.m[4] = m1.m[1] * m2.m[3] + m1.m[4] * m2.m[4] + m1.m[7] * m2.m[5]; + r.m[5] = m1.m[2] * m2.m[3] + m1.m[5] * m2.m[4] + m1.m[8] * m2.m[5]; + + r.m[6] = m1.m[0] * m2.m[6] + m1.m[3] * m2.m[7] + m1.m[6] * m2.m[8] ; + r.m[7] = m1.m[1] * m2.m[6] + m1.m[4] * m2.m[7] + m1.m[7] * m2.m[8]; + r.m[8] = m1.m[2] * m2.m[6] + m1.m[5] * m2.m[7] + m1.m[8] * m2.m[8]; return r; } @@ -369,6 +634,18 @@ namespace ZL { return r; } + Vector4f operator*(Vector4f v, float scale) + { + Vector4f r = v; + + r.v[0] = v.v[0] * scale; + r.v[1] = v.v[1] * scale; + r.v[2] = v.v[2] * scale; + r.v[3] = v.v[3] * scale; + + return r; + } + Vector3f MultVectorMatrix(Vector3f v, Matrix3f mt) { Vector3f r; @@ -380,4 +657,118 @@ namespace ZL { return r; } + Vector4f MultVectorMatrix(Vector4f v, Matrix4f mt) + { + Vector4f r; + + r.v[0] = v.v[0] * mt.m[0] + v.v[1] * mt.m[1] + v.v[2] * mt.m[2] + v.v[3] * mt.m[3]; + r.v[1] = v.v[0] * mt.m[4] + v.v[1] * mt.m[5] + v.v[2] * mt.m[6] + v.v[3] * mt.m[7]; + r.v[2] = v.v[0] * mt.m[8] + v.v[1] * mt.m[9] + v.v[2] * mt.m[10] + v.v[3] * mt.m[11]; + r.v[3] = v.v[0] * mt.m[12] + v.v[1] * mt.m[13] + v.v[2] * mt.m[14] + v.v[3] * mt.m[15]; + + return r; + } + + Vector4f MultMatrixVector(Matrix4f mt, Vector4f v) + { + Vector4f r; + + r.v[0] = v.v[0] * mt.m[0] + v.v[1] * mt.m[4] + v.v[2] * mt.m[8] + v.v[3] * mt.m[12]; + r.v[1] = v.v[0] * mt.m[1] + v.v[1] * mt.m[5] + v.v[2] * mt.m[9] + v.v[3] * mt.m[13]; + r.v[2] = v.v[0] * mt.m[2] + v.v[1] * mt.m[6] + v.v[2] * mt.m[10] + v.v[3] * mt.m[14]; + r.v[3] = v.v[0] * mt.m[3] + v.v[1] * mt.m[7] + v.v[2] * mt.m[11] + v.v[3] * mt.m[15]; + + return r; + } + + Vector4f slerp(const Vector4f& q1, const Vector4f& q2, double t) + { + // Вычисляем косинус угла между кватернионами + double cosTheta = q1.dot(q2); + + // Если cosTheta < 0, меняем знак второго кватерниона, чтобы выбрать кратчайший путь + Vector4f q2Adjusted = q2; + if (cosTheta < 0.0) { + //q2Adjusted = { -q2.w, -q2.x, -q2.y, -q2.z }; + q2Adjusted.v[0] = -q2.v[0]; + q2Adjusted.v[1] = -q2.v[1]; + q2Adjusted.v[2] = -q2.v[2]; + q2Adjusted.v[3] = -q2.v[3]; + cosTheta = -cosTheta; + } + + // Если кватернионы близки, используем линейную интерполяцию + const double epsilon = 1e-6; + if (cosTheta > 1.0 - epsilon) { + + Vector4f result; + + result.v[0] = q1.v[0] + t * (q2Adjusted.v[0] - q1.v[0]); + result.v[1] = q1.v[1] + t * (q2Adjusted.v[1] - q1.v[1]); + result.v[2] = q1.v[2] + t * (q2Adjusted.v[2] - q1.v[2]); + result.v[3] = q1.v[3] + t * (q2Adjusted.v[3] - q1.v[3]); + + /*Quaternion result = { + q1.w + t * (q2Adjusted.w - q1.w), + q1.x + t * (q2Adjusted.x - q1.x), + q1.y + t * (q2Adjusted.y - q1.y), + q1.z + t * (q2Adjusted.z - q1.z) + };*/ + return result.normalized(); + } + + // Вычисляем угол theta + double theta = std::acos(cosTheta); + double sinTheta = std::sin(theta); + + // Вычисляем коэффициенты для интерполяции + double coeff1 = std::sin((1.0 - t) * theta) / sinTheta; + double coeff2 = std::sin(t * theta) / sinTheta; + + // Интерполируем + /* + Quaternion result = { + coeff1 * q1.w + coeff2 * q2Adjusted.w, + coeff1 * q1.x + coeff2 * q2Adjusted.x, + coeff1 * q1.y + coeff2 * q2Adjusted.y, + coeff1 * q1.z + coeff2 * q2Adjusted.z + };*/ + Vector4f result; + + result.v[0] = coeff1 * q1.v[0] + coeff2 * q2Adjusted.v[0]; + result.v[1] = coeff1 * q1.v[1] + coeff2 * q2Adjusted.v[1]; + result.v[2] = coeff1 * q1.v[2] + coeff2 * q2Adjusted.v[2]; + result.v[3] = coeff1 * q1.v[3] + coeff2 * q2Adjusted.v[3]; + + + return result.normalized(); + } + + Matrix4f MakeMatrix4x4(const Matrix3f& m, const Vector3f pos) + { + Matrix4f r; + + r.m[0] = m.m[0]; + r.m[1] = m.m[1]; + r.m[2] = m.m[2]; + r.m[3] = 0; + + r.m[4] = m.m[3]; + r.m[5] = m.m[4]; + r.m[6] = m.m[5]; + r.m[7] = 0; + + r.m[8] = m.m[6]; + r.m[9] = m.m[7]; + r.m[10] = m.m[8]; + r.m[11] = 0; + + r.m[12] = pos.v[0]; + r.m[13] = pos.v[1]; + r.m[14] = pos.v[2]; + r.m[15] = 1.0; + return r; + } + + }; diff --git a/Math.h b/Math.h index 0bba92e..329ee9d 100755 --- a/Math.h +++ b/Math.h @@ -3,13 +3,29 @@ #include #include #include - +#include namespace ZL { struct Vector4f { std::array v = { 0.f, 0.f, 0.f, 0.f }; + + Vector4f normalized() const { + double norm = std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); + Vector4f r; + + r.v[0] = v[0] / norm; + r.v[1] = v[1] / norm; + r.v[2] = v[2] / norm; + r.v[3] = v[3] / norm; + + return r; + } + + double dot(const Vector4f& other) const { + return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2] + v[3] * other.v[3]; + } }; struct Vector3f @@ -25,6 +41,14 @@ namespace ZL { Vector2f operator+(const Vector2f& x, const Vector2f& y); Vector2f operator-(const Vector2f& x, const Vector2f& y); + + Vector3f operator+(const Vector3f& x, const Vector3f& y); + + Vector3f operator-(const Vector3f& x, const Vector3f& y); + Vector4f operator+(const Vector4f& x, const Vector4f& y); + + Vector4f operator-(const Vector4f& x, const Vector4f& y); + struct Matrix3f { @@ -43,6 +67,16 @@ namespace ZL { 0.f, 0.f, 0.f, 0.f }; static Matrix4f Identity(); + + float& operator()(int row, int col) { + //return m[row * 4 + col]; //OpenGL specific + return m[col * 4 + row]; + } + + const float& operator()(int row, int col) const { + //return m[row * 4 + col]; + return m[col * 4 + row]; + } }; Matrix4f operator*(const Matrix4f& m1, const Matrix4f& m2); @@ -53,12 +87,24 @@ namespace ZL { Matrix3f QuatToMatrix(const Vector4f& q); + Vector4f MatrixToQuat(const Matrix3f& m); + Vector4f QuatFromRotateAroundX(float angle); Vector4f QuatFromRotateAroundY(float angle); Vector4f QuatFromRotateAroundZ(float angle); Vector3f operator*(Vector3f v, float scale); + Vector4f operator*(Vector4f v, float scale); Vector3f MultVectorMatrix(Vector3f v, Matrix3f mt); + Vector4f MultVectorMatrix(Vector4f v, Matrix4f mt); + Vector4f MultMatrixVector(Matrix4f mt, Vector4f v); + + Vector4f slerp(const Vector4f& q1, const Vector4f& q2, double t); + Matrix3f InverseMatrix(const Matrix3f& m); + Matrix4f InverseMatrix(const Matrix4f& m); + Matrix3f MultMatrixMatrix(const Matrix3f& m1, const Matrix3f& m2); + Matrix4f MultMatrixMatrix(const Matrix4f& m1, const Matrix4f& m2); + Matrix4f MakeMatrix4x4(const Matrix3f& m, const Vector3f pos); }; \ No newline at end of file diff --git a/TextureManager.cpp b/TextureManager.cpp index 9053dc9..8a63e74 100755 --- a/TextureManager.cpp +++ b/TextureManager.cpp @@ -1,5 +1,7 @@ #include "TextureManager.h" +#ifdef PNG_ENABLED #include "png.h" +#endif namespace ZL { @@ -164,6 +166,8 @@ namespace ZL return texData; } +#ifdef PNG_ENABLED + TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName) { TextureDataStruct texData; @@ -272,5 +276,5 @@ namespace ZL return texData; } - +#endif } \ No newline at end of file diff --git a/TextureManager.h b/TextureManager.h index ada4eba..e46da1f 100755 --- a/TextureManager.h +++ b/TextureManager.h @@ -41,5 +41,7 @@ namespace ZL TextureDataStruct CreateTextureDataFromBmp24(const std::string& fullFileName); TextureDataStruct CreateTextureDataFromBmp32(const std::string& fullFileName); +#ifdef PNG_ENABLED TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName); +#endif } diff --git a/ZeptoLabTest1.vcxproj b/ZeptoLabTest1.vcxproj index 4cff053..456ea75 100755 --- a/ZeptoLabTest1.vcxproj +++ b/ZeptoLabTest1.vcxproj @@ -145,6 +145,7 @@ + @@ -159,6 +160,7 @@ + diff --git a/ZeptoLabTest1.vcxproj.filters b/ZeptoLabTest1.vcxproj.filters index dc6acc6..b6e5b54 100755 --- a/ZeptoLabTest1.vcxproj.filters +++ b/ZeptoLabTest1.vcxproj.filters @@ -48,6 +48,9 @@ Source Files + + Source Files + @@ -83,5 +86,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/defaultColor.fragment b/defaultColor.fragment index d0c63fb..1e3d8c1 100644 --- a/defaultColor.fragment +++ b/defaultColor.fragment @@ -3,6 +3,7 @@ varying vec3 color; void main() { - gl_FragColor = vec4(color, 1.0); + //gl_FragColor = vec4(color, 1.0); + gl_FragColor = vec4(1.0, 1.0, 0.5, 1.0); } \ No newline at end of file diff --git a/main.cpp b/main.cpp index f1aa5b5..bbaf134 100755 --- a/main.cpp +++ b/main.cpp @@ -14,6 +14,7 @@ #include "Game.h" #include "AnimatedModel.h" +#include "BoneAnimatedModel.h" ZL::AnimatedModel testLoadModel(); @@ -135,20 +136,24 @@ namespace ZL glViewport(0, 0, Env::width, Env::height); - renderer.shaderManager.PushShader(defaultShaderName); - renderer.RenderUniform1i(textureUniformName, 0); + //renderer.shaderManager.PushShader(defaultShaderName); + renderer.shaderManager.PushShader(colorShaderName); + //renderer.RenderUniform1i(textureUniformName, 0); renderer.EnableVertexAttribArray(vPositionName); - renderer.EnableVertexAttribArray(vTexCoordName); + //renderer.EnableVertexAttribArray(vTexCoordName); - renderer.PushPerspectiveProjectionMatrix(1.0 / 6.0, static_cast(Env::width) / static_cast(Env::height), 100, 100000); + renderer.PushPerspectiveProjectionMatrix(1.0 / 6.0, static_cast(Env::width) / static_cast(Env::height), 0.1, 1000); renderer.PushMatrix(); renderer.LoadIdentity(); - renderer.TranslateMatrix({ 0,0, -30000 }); + renderer.TranslateMatrix({ 0,0, -200 }); + renderer.RotateMatrix(QuatFromRotateAroundX(-M_PI / 2.0)); + //renderer.RotateMatrix(QuatFromRotateAroundZ(-M_PI / 4.0)); + /* renderer.RotateMatrix(QuatFromRotateAroundX(-M_PI / 3.0)); @@ -162,7 +167,7 @@ namespace ZL renderer.DrawVertexRenderStruct(GameObjects::testmd3.parts[i].renderMeshes[j]); } } - + */ /* GameObjects::testObjMeshMutable.AssignFrom(GameObjects::testObjMesh); GameObjects::testObjMeshMutable.data.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundZ(gs.rotateTimer * M_PI / 3.0))); @@ -180,12 +185,17 @@ namespace ZL renderer.DrawVertexRenderStruct(GameObjects::testmd3mutable[0]); renderer.DrawVertexRenderStruct(GameObjects::testmd3mutable[1]); */ + + GameObjects::bxMutable.AssignFrom(GameObjects::bx.mesh); + GameObjects::bxMutable.RefreshVBO(); + renderer.DrawVertexRenderStruct(GameObjects::bxMutable); + renderer.PopMatrix(); renderer.PopProjectionMatrix(); renderer.DisableVertexAttribArray(vPositionName); - renderer.DisableVertexAttribArray(vTexCoordName); + //renderer.DisableVertexAttribArray(vTexCoordName); renderer.shaderManager.PopShader(); @@ -294,10 +304,14 @@ namespace ZL GameObjects::backgroundTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./background.bmp")); GameObjects::pipeTexturePtr = std::make_shared(CreateTextureDataFromBmp32("./pipe.bmp32")); GameObjects::gameOverTexturePtr = std::make_shared(CreateTextureDataFromBmp32("./game_over.bmp32")); - GameObjects::testObjTexturePtr = std::make_shared(CreateTextureDataFromPng("./chair_01_Base_Color.png")); + //GameObjects::testObjTexturePtr = std::make_shared(CreateTextureDataFromPng("./chair_01_Base_Color.png")); + GameObjects::testObjTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./chair_01_Base_Color.bmp")); //GameObjects::md3TexturePtr = std::make_shared(CreateTextureDataFromPng("./model/sarge/band.png")); + GameObjects::bx.LoadFromFile("C:\\Work\\GameJam2025-02\\mesh_armature_and_animation_data.txt"); + //GameObjects::bx.LoadFromFile("C:\\Work\\GameJam2025-02\\mesh_armature_and_animation_data02.txt"); + CheckGlError(); //Create bird mesh @@ -374,6 +388,11 @@ namespace ZL } if (event.type == SDL_MOUSEBUTTONDOWN) { + static int x = 0; + + GameObjects::bx.Interpolate(x); + x = x + 2; + /* if (gs.isGameOver) { gs.RestartGame(); @@ -381,7 +400,7 @@ namespace ZL else { gs.BirdJump(); - } + }*/ } } diff --git a/md3test.cpp b/md3test.cpp index 063ddfc..f725dfb 100644 --- a/md3test.cpp +++ b/md3test.cpp @@ -1034,7 +1034,8 @@ ZL::AnimatedModel CMD3::convertToAnimatedModel() for (int i = 0; i < textureNames[m].size(); i++) { std::string texName = textureNames[m][i]; - result.parts[m].textures.push_back(std::make_shared(ZL::CreateTextureDataFromPng(texName))); + //result.parts[m].textures.push_back(std::make_shared(ZL::CreateTextureDataFromPng(texName))); + result.parts[m].textures.push_back(std::make_shared(ZL::CreateTextureDataFromBmp24("chair_01_Base_Color.bmp"))); } for (int n = 0; n < numMeshes; n++)