Compare commits
No commits in common. "66da012d5a40c36298b9f24036e7453d1b6dcd2e" and "b633aa01f52c89063b47fbedef4462a42566f5a9" have entirely different histories.
66da012d5a
...
b633aa01f5
@ -30,8 +30,6 @@ add_executable(space-game001
|
||||
../src/AudioPlayerAsync.h
|
||||
../src/BoneAnimatedModel.cpp
|
||||
../src/BoneAnimatedModel.h
|
||||
../src/BoneAnimatedModelNew.cpp
|
||||
../src/BoneAnimatedModelNew.h
|
||||
../src/render/OpenGlExtensions.cpp
|
||||
../src/render/OpenGlExtensions.h
|
||||
../src/utils/Utils.cpp
|
||||
|
||||
BIN
resources/e/female_packed0_diffuse.png
(Stored with Git LFS)
BIN
resources/e/female_packed0_diffuse.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/e/female_packed1_diffuse.png
(Stored with Git LFS)
BIN
resources/e/female_packed1_diffuse.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/e/female_packed2_diffuse.png
(Stored with Git LFS)
BIN
resources/e/female_packed2_diffuse.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/e/female_packed3_diffuse.png
(Stored with Git LFS)
BIN
resources/e/female_packed3_diffuse.png
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
resources/e/male_packed0_diffuse.png
(Stored with Git LFS)
BIN
resources/e/male_packed0_diffuse.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/e/male_packed1_diffuse.png
(Stored with Git LFS)
BIN
resources/e/male_packed1_diffuse.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/e/male_packed2_diffuse.png
(Stored with Git LFS)
BIN
resources/e/male_packed2_diffuse.png
(Stored with Git LFS)
Binary file not shown.
237188
resources/e/woman_run001.txt
237188
resources/e/woman_run001.txt
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1,684 +0,0 @@
|
||||
#include "BoneAnimatedModelNew.h"
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
namespace ZL
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
using std::min;
|
||||
using std::max;
|
||||
#endif
|
||||
|
||||
extern int getIndexByValue(const std::string& name, const std::vector<std::string>& words);
|
||||
|
||||
static std::string trimRight(const std::string& s)
|
||||
{
|
||||
size_t end = s.size();
|
||||
while (end > 0 && (s[end - 1] == '\r' || s[end - 1] == '\n' || s[end - 1] == ' ' || s[end - 1] == '\t'))
|
||||
end--;
|
||||
return s.substr(0, end);
|
||||
}
|
||||
|
||||
void BoneSystemNew::LoadFromFile(const std::string& fileName, const std::string& ZIPFileName)
|
||||
{
|
||||
std::ifstream filestream;
|
||||
std::istringstream zipStream;
|
||||
|
||||
if (!ZIPFileName.empty())
|
||||
{
|
||||
std::vector<char> fileData = readFileFromZIP(fileName, ZIPFileName);
|
||||
std::string fileContents(fileData.begin(), fileData.end());
|
||||
zipStream.str(fileContents);
|
||||
}
|
||||
else
|
||||
{
|
||||
filestream.open(fileName);
|
||||
}
|
||||
|
||||
std::istream& f = (!ZIPFileName.empty()) ? static_cast<std::istream&>(zipStream) : static_cast<std::istream&>(filestream);
|
||||
|
||||
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;
|
||||
std::string tempLine;
|
||||
|
||||
// ---- Armature matrix (4 lines after the header) ----
|
||||
std::getline(f, tempLine); // === Armature Matrix ===
|
||||
armatureMatrix = Matrix4f::Identity();
|
||||
for (int r = 0; r < 4; r++)
|
||||
{
|
||||
std::getline(f, tempLine);
|
||||
std::vector<float> 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;
|
||||
}
|
||||
if (floatValues.size() >= 4)
|
||||
{
|
||||
for (int c = 0; c < 4; c++)
|
||||
armatureMatrix.data()[r + c * 4] = floatValues[c];
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Bones ----
|
||||
std::getline(f, tempLine); // === Armature Bones: N
|
||||
int numberBones;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
numberBones = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Armature bones count not found");
|
||||
}
|
||||
|
||||
std::vector<Bone> bones;
|
||||
std::vector<std::string> boneNames;
|
||||
std::vector<std::string> boneParentNames;
|
||||
std::unordered_map<std::string, std::vector<std::string>> boneChildren;
|
||||
|
||||
bones.resize(numberBones);
|
||||
boneNames.resize(numberBones);
|
||||
boneParentNames.resize(numberBones);
|
||||
|
||||
for (int i = 0; i < numberBones; i++)
|
||||
{
|
||||
std::getline(f, tempLine); // Bone: name
|
||||
std::string boneName = trimRight(tempLine.substr(6));
|
||||
boneNames[i] = boneName;
|
||||
|
||||
std::getline(f, tempLine); // HEAD_LOCAL
|
||||
std::vector<float> 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); // TAIL_LOCAL
|
||||
|
||||
std::getline(f, tempLine); // Length
|
||||
if (std::regex_search(tempLine, match, pattern_float)) {
|
||||
bones[i].boneLength = std::stof(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Bone length not found");
|
||||
}
|
||||
|
||||
// 3x3 matrix
|
||||
for (int r = 0; r < 3; r++)
|
||||
{
|
||||
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.data()[r] = floatValues[0];
|
||||
bones[i].boneMatrixWorld.data()[r + 1 * 3] = floatValues[1];
|
||||
bones[i].boneMatrixWorld.data()[r + 2 * 3] = floatValues[2];
|
||||
}
|
||||
|
||||
std::getline(f, tempLine); // Parent
|
||||
std::string parentLine = trimRight(tempLine);
|
||||
if (parentLine == " Parent: None")
|
||||
{
|
||||
bones[i].parent = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
boneParentNames[i] = parentLine.substr(10);
|
||||
}
|
||||
|
||||
std::getline(f, tempLine); // Children
|
||||
auto bc = tempLine.cbegin();
|
||||
auto ec = tempLine.cend();
|
||||
while (std::regex_search(bc, ec, match, pattern_boneChildren)) {
|
||||
boneChildren[boneName].push_back(match.str(1));
|
||||
bc = match.suffix().first;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve parent/child indices
|
||||
for (int i = 0; i < numberBones; i++)
|
||||
{
|
||||
const std::string& boneName = boneNames[i];
|
||||
const std::string& boneParent = boneParentNames[i];
|
||||
if (boneParent == "" || boneParent == "None")
|
||||
bones[i].parent = -1;
|
||||
else
|
||||
bones[i].parent = getIndexByValue(boneParent, boneNames);
|
||||
|
||||
for (size_t j = 0; j < boneChildren[boneName].size(); j++)
|
||||
bones[i].children.push_back(getIndexByValue(boneChildren[boneName][j], boneNames));
|
||||
}
|
||||
|
||||
startBones = bones;
|
||||
currentBones = bones;
|
||||
|
||||
// ---- Multi-mesh header ----
|
||||
std::getline(f, tempLine); // === TOTAL MESHES TO EXPORT: N ===
|
||||
int numberMeshes;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
numberMeshes = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Total meshes count not found");
|
||||
}
|
||||
|
||||
for (int meshIdx = 0; meshIdx < numberMeshes; meshIdx++)
|
||||
{
|
||||
// === Mesh Object: Name ===
|
||||
std::getline(f, tempLine);
|
||||
std::string meshHeader = trimRight(tempLine);
|
||||
// Extract mesh name: strip "=== Mesh Object: " prefix and " ===" suffix
|
||||
const std::string prefix = "=== Mesh Object: ";
|
||||
const std::string suffix = " ===";
|
||||
std::string meshName;
|
||||
if (meshHeader.size() >= prefix.size() + suffix.size() &&
|
||||
meshHeader.compare(0, prefix.size(), prefix) == 0 &&
|
||||
meshHeader.compare(meshHeader.size() - suffix.size(), suffix.size(), suffix) == 0)
|
||||
{
|
||||
meshName = meshHeader.substr(prefix.size(),
|
||||
meshHeader.size() - prefix.size() - suffix.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Invalid mesh header: " + meshHeader);
|
||||
}
|
||||
|
||||
MeshBoneData meshData;
|
||||
|
||||
// Vertices
|
||||
std::getline(f, tempLine); // ===Vertices: N
|
||||
int numberVertices;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
numberVertices = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Vertex count not found for mesh " + meshName);
|
||||
}
|
||||
|
||||
std::vector<Vector3f> vertices(numberVertices);
|
||||
for (int i = 0; i < numberVertices; i++)
|
||||
{
|
||||
std::getline(f, tempLine);
|
||||
std::vector<float> 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] };
|
||||
}
|
||||
|
||||
// UV coordinates
|
||||
std::getline(f, tempLine); // ===UV Coordinates:
|
||||
std::getline(f, tempLine); // Face count: M
|
||||
int numberFaces;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
numberFaces = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Face count not found for mesh " + meshName);
|
||||
}
|
||||
|
||||
std::vector<std::array<Vector2f, 3>> uvCoords(numberFaces);
|
||||
for (int i = 0; i < numberFaces; i++)
|
||||
{
|
||||
std::getline(f, tempLine); // Face X
|
||||
std::getline(f, tempLine); // UV Count: 3
|
||||
int uvCount;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
uvCount = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("UV count not found");
|
||||
}
|
||||
if (uvCount != 3)
|
||||
throw std::runtime_error("more than 3 uvs");
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
std::getline(f, tempLine); // UV <Vector (u, v)>
|
||||
std::vector<float> 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;
|
||||
}
|
||||
if (floatValues.size() != 2)
|
||||
throw std::runtime_error("more than 2 uvs---");
|
||||
uvCoords[i][j] = Vector2f{ floatValues[0], floatValues[1] };
|
||||
}
|
||||
}
|
||||
|
||||
// Normals
|
||||
std::getline(f, tempLine); // ===Normals:
|
||||
std::vector<Vector3f> normals(numberVertices);
|
||||
for (int i = 0; i < numberVertices; i++)
|
||||
{
|
||||
std::getline(f, tempLine);
|
||||
std::vector<float> 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;
|
||||
}
|
||||
normals[i] = Vector3f{ floatValues[0], floatValues[1], floatValues[2] };
|
||||
}
|
||||
|
||||
// Triangles
|
||||
std::getline(f, tempLine); // ===Triangles: M
|
||||
int numberTriangles;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
numberTriangles = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Triangle count not found for mesh " + meshName);
|
||||
}
|
||||
|
||||
std::vector<std::array<int, 3>> triangles(numberTriangles);
|
||||
for (int i = 0; i < numberTriangles; i++)
|
||||
{
|
||||
std::getline(f, tempLine);
|
||||
std::vector<int> 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] };
|
||||
}
|
||||
|
||||
// Vertex weights
|
||||
std::getline(f, tempLine); // === Vertex Weights (Max 5 bones per vertex) ===
|
||||
std::vector<std::array<BoneWeight, MAX_BONE_COUNT>> localVerticesBoneWeight(numberVertices);
|
||||
for (int i = 0; i < numberVertices; i++)
|
||||
{
|
||||
std::getline(f, tempLine); // Vertex X:
|
||||
std::getline(f, tempLine); // Vertex groups: K
|
||||
int boneCount;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
boneCount = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Vertex group count not found");
|
||||
}
|
||||
if (boneCount > MAX_BONE_COUNT)
|
||||
throw std::runtime_error("more than 5 bones");
|
||||
|
||||
float sumWeights = 0;
|
||||
for (int j = 0; j < boneCount; j++)
|
||||
{
|
||||
std::getline(f, tempLine);
|
||||
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 = static_cast<float>(weight);
|
||||
sumWeights += static_cast<float>(weight);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("No match found in bone weight line");
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < boneCount; j++)
|
||||
localVerticesBoneWeight[i][j].weight /= sumWeights;
|
||||
}
|
||||
|
||||
// Build per-triangle expanded mesh
|
||||
for (int i = 0; i < numberTriangles; i++)
|
||||
{
|
||||
meshData.mesh.PositionData.push_back(vertices[triangles[i][0]]);
|
||||
meshData.mesh.PositionData.push_back(vertices[triangles[i][1]]);
|
||||
meshData.mesh.PositionData.push_back(vertices[triangles[i][2]]);
|
||||
|
||||
meshData.verticesBoneWeight.push_back(localVerticesBoneWeight[triangles[i][0]]);
|
||||
meshData.verticesBoneWeight.push_back(localVerticesBoneWeight[triangles[i][1]]);
|
||||
meshData.verticesBoneWeight.push_back(localVerticesBoneWeight[triangles[i][2]]);
|
||||
|
||||
meshData.mesh.TexCoordData.push_back(uvCoords[i][0]);
|
||||
meshData.mesh.TexCoordData.push_back(uvCoords[i][1]);
|
||||
meshData.mesh.TexCoordData.push_back(uvCoords[i][2]);
|
||||
}
|
||||
|
||||
meshData.startMesh = meshData.mesh;
|
||||
|
||||
meshes[meshName] = std::move(meshData);
|
||||
meshNamesOrdered.push_back(meshName);
|
||||
}
|
||||
|
||||
std::cout << "Loaded " << numberMeshes << " meshes from " << fileName << std::endl;
|
||||
|
||||
// ---- Animation Keyframes ----
|
||||
std::getline(f, tempLine); // === Animation Keyframes ===
|
||||
std::getline(f, tempLine); // === Bone Transforms per Keyframe ===
|
||||
std::getline(f, tempLine); // Keyframes: N
|
||||
int numberKeyFrames;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
numberKeyFrames = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Keyframe count not found");
|
||||
}
|
||||
|
||||
animations.resize(1);
|
||||
animations[0].keyFrames.resize(numberKeyFrames);
|
||||
|
||||
for (int i = 0; i < numberKeyFrames; i++)
|
||||
{
|
||||
std::getline(f, tempLine); // Frame: N
|
||||
int numberFrame;
|
||||
if (std::regex_search(tempLine, match, pattern_count)) {
|
||||
numberFrame = std::stoi(match.str());
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Frame number not found");
|
||||
}
|
||||
|
||||
animations[0].keyFrames[i].frame = numberFrame;
|
||||
animations[0].keyFrames[i].bones.resize(numberBones);
|
||||
|
||||
for (int j = 0; j < numberBones; j++)
|
||||
{
|
||||
std::getline(f, tempLine); // Bone: name
|
||||
std::string boneName = trimRight(tempLine.substr(8));
|
||||
int boneNumber = getIndexByValue(boneName, boneNames);
|
||||
animations[0].keyFrames[i].bones[boneNumber] = startBones[boneNumber];
|
||||
|
||||
std::getline(f, tempLine); // Location
|
||||
std::vector<float> 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:
|
||||
|
||||
for (int r = 0; r < 4; r++)
|
||||
{
|
||||
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.data()[r] = floatValues[0];
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[r + 1 * 4] = floatValues[1];
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[r + 2 * 4] = floatValues[2];
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[r + 3 * 4] = floatValues[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (startBones.size() > MAX_GPU_BONES)
|
||||
{
|
||||
std::cout << "Warning: model has " << startBones.size()
|
||||
<< " bones, exceeding GPU skinning limit of " << MAX_GPU_BONES << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void BoneSystemNew::Interpolate(int frame)
|
||||
{
|
||||
int startingKeyFrame = -1;
|
||||
for (int i = 0; i < static_cast<int>(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)
|
||||
{
|
||||
startingKeyFrame = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (startingKeyFrame == -1)
|
||||
{
|
||||
std::cout << "Exception here: frame number is out of range of keyframes. Frame: " << frame << std::endl;
|
||||
throw std::runtime_error("Exception here");
|
||||
}
|
||||
|
||||
int modifiedFrameNumber = frame - animations[0].keyFrames[startingKeyFrame].frame;
|
||||
int diffFrames = animations[0].keyFrames[startingKeyFrame + 1].frame - animations[0].keyFrames[startingKeyFrame].frame;
|
||||
float t = (modifiedFrameNumber + 0.f) / diffFrames;
|
||||
|
||||
std::vector<Bone>& oneFrameBones = animations[0].keyFrames[startingKeyFrame].bones;
|
||||
std::vector<Bone>& nextFrameBones = animations[0].keyFrames[startingKeyFrame + 1].bones;
|
||||
|
||||
std::vector<Matrix4f> skinningMatrixForEachBone(currentBones.size());
|
||||
|
||||
for (size_t i = 0; i < currentBones.size(); i++)
|
||||
{
|
||||
currentBones[i].boneStartWorld(0) = oneFrameBones[i].boneStartWorld(0) + t * (nextFrameBones[i].boneStartWorld(0) - oneFrameBones[i].boneStartWorld(0));
|
||||
currentBones[i].boneStartWorld(1) = oneFrameBones[i].boneStartWorld(1) + t * (nextFrameBones[i].boneStartWorld(1) - oneFrameBones[i].boneStartWorld(1));
|
||||
currentBones[i].boneStartWorld(2) = oneFrameBones[i].boneStartWorld(2) + t * (nextFrameBones[i].boneStartWorld(2) - oneFrameBones[i].boneStartWorld(2));
|
||||
|
||||
Matrix3f oneFrameBonesMatrix = oneFrameBones[i].boneMatrixWorld.block<3, 3>(0, 0);
|
||||
Matrix3f nextFrameBonesMatrix = nextFrameBones[i].boneMatrixWorld.block<3, 3>(0, 0);
|
||||
|
||||
Eigen::Quaternionf q1 = Eigen::Quaternionf(oneFrameBonesMatrix).normalized();
|
||||
Eigen::Quaternionf q2 = Eigen::Quaternionf(nextFrameBonesMatrix).normalized();
|
||||
Eigen::Quaternionf result = q1.slerp(t, q2);
|
||||
|
||||
Matrix3f boneMatrixWorld3 = result.toRotationMatrix();
|
||||
|
||||
currentBones[i].boneMatrixWorld = Eigen::Matrix4f::Identity();
|
||||
currentBones[i].boneMatrixWorld.block<3, 3>(0, 0) = boneMatrixWorld3;
|
||||
currentBones[i].boneMatrixWorld.block<3, 1>(0, 3) = currentBones[i].boneStartWorld;
|
||||
|
||||
Matrix4f startBoneMatrixWorld4 = animations[0].keyFrames[0].bones[i].boneMatrixWorld;
|
||||
skinningMatrixForEachBone[i] = currentBones[i].boneMatrixWorld * startBoneMatrixWorld4.inverse();
|
||||
}
|
||||
|
||||
for (const auto& name : meshNamesOrdered)
|
||||
{
|
||||
auto it = meshes.find(name);
|
||||
if (it == meshes.end()) continue;
|
||||
MeshBoneData& md = it->second;
|
||||
|
||||
for (size_t i = 0; i < md.mesh.PositionData.size(); i++)
|
||||
{
|
||||
Vector4f originalPos = {
|
||||
md.startMesh.PositionData[i](0),
|
||||
md.startMesh.PositionData[i](1),
|
||||
md.startMesh.PositionData[i](2), 1.0f };
|
||||
|
||||
Vector4f finalPos = Vector4f{ 0.f, 0.f, 0.f, 0.f };
|
||||
bool vMoved = false;
|
||||
|
||||
for (int j = 0; j < MAX_BONE_COUNT; j++)
|
||||
{
|
||||
if (md.verticesBoneWeight[i][j].weight != 0)
|
||||
{
|
||||
if (md.verticesBoneWeight[i][j].boneIndex == -1)
|
||||
{
|
||||
std::cout << "Exception here: bone index is -1 but weight is > 0" << std::endl;
|
||||
throw std::runtime_error("Bones loaded incorrectly - bone index is -1 but weight is > 0");
|
||||
}
|
||||
vMoved = true;
|
||||
finalPos = finalPos + (skinningMatrixForEachBone[md.verticesBoneWeight[i][j].boneIndex] * originalPos) * md.verticesBoneWeight[i][j].weight;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vMoved) finalPos = originalPos;
|
||||
|
||||
md.mesh.PositionData[i](0) = finalPos(0);
|
||||
md.mesh.PositionData[i](1) = finalPos(1);
|
||||
md.mesh.PositionData[i](2) = finalPos(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshGpuSkinningData::prepareGpuSkinningVBOs(MeshBoneData& meshData)
|
||||
{
|
||||
if (gpuSkinningPrepared) return;
|
||||
|
||||
gpuBoneData.PrepareGpuSkinningData(meshData.verticesBoneWeight);
|
||||
bindPoseMutable.AssignFrom(meshData.startMesh);
|
||||
|
||||
auto& gpu = gpuBoneData;
|
||||
|
||||
boneIndices0VBO = std::make_shared<VBOHolder>();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneIndices0VBO->getBuffer());
|
||||
glBufferData(GL_ARRAY_BUFFER, gpu.boneIndices0.size() * sizeof(Eigen::Vector4f),
|
||||
gpu.boneIndices0.data(), GL_STATIC_DRAW);
|
||||
|
||||
boneIndices1VBO = std::make_shared<VBOHolder>();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneIndices1VBO->getBuffer());
|
||||
glBufferData(GL_ARRAY_BUFFER, gpu.boneIndices1.size() * sizeof(Eigen::Vector2f),
|
||||
gpu.boneIndices1.data(), GL_STATIC_DRAW);
|
||||
|
||||
boneWeights0VBO = std::make_shared<VBOHolder>();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneWeights0VBO->getBuffer());
|
||||
glBufferData(GL_ARRAY_BUFFER, gpu.boneWeights0.size() * sizeof(Eigen::Vector4f),
|
||||
gpu.boneWeights0.data(), GL_STATIC_DRAW);
|
||||
|
||||
boneWeights1VBO = std::make_shared<VBOHolder>();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneWeights1VBO->getBuffer());
|
||||
glBufferData(GL_ARRAY_BUFFER, gpu.boneWeights1.size() * sizeof(Eigen::Vector2f),
|
||||
gpu.boneWeights1.data(), GL_STATIC_DRAW);
|
||||
|
||||
gpuSkinningPrepared = true;
|
||||
}
|
||||
|
||||
void MeshGpuSkinningData::RenderVBO(Renderer& renderer)
|
||||
{
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, bindPoseMutable.positionVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vPosition", 0, NULL);
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
|
||||
if (bindPoseMutable.texCoordVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, bindPoseMutable.texCoordVBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("vTexCoord", 0, NULL);
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
if (bindPoseMutable.normalVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, bindPoseMutable.normalVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vNormal", 0, NULL);
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
} else {
|
||||
renderer.DisableVertexAttribArray("vNormal");
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneIndices0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneIndices0", 0, NULL);
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneIndices1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneIndices1", 0, NULL);
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneWeights0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneWeights0", 0, NULL);
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boneWeights1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneWeights1", 0, NULL);
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(bindPoseMutable.data.PositionData.size()));
|
||||
}
|
||||
|
||||
void GpuSkinningShaderDataNew::prepareGpuSkinningVBOs(BoneSystemNew& model)
|
||||
{
|
||||
for (const auto& name : model.meshNamesOrdered)
|
||||
{
|
||||
auto it = model.meshes.find(name);
|
||||
if (it == model.meshes.end()) continue;
|
||||
perMesh[name].prepareGpuSkinningVBOs(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void GpuSkinningShaderDataNew::RenderVBO(Renderer& renderer, const std::vector<std::string>& meshNamesOrdered)
|
||||
{
|
||||
for (const auto& name : meshNamesOrdered)
|
||||
{
|
||||
auto it = perMesh.find(name);
|
||||
if (it == perMesh.end()) continue;
|
||||
it->second.RenderVBO(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
void GpuSkinningShaderDataNew::ComputeSkinningMatrices(const std::vector<Bone>& startBones, const std::vector<AnimationKeyFrame>& keyFrames, int frame)
|
||||
{
|
||||
int startingKeyFrame = -1;
|
||||
for (size_t i = 0; i < keyFrames.size() - 1; i++)
|
||||
{
|
||||
int oldFrame = keyFrames[i].frame;
|
||||
int nextFrame = keyFrames[i + 1].frame;
|
||||
if (frame >= oldFrame && frame < nextFrame)
|
||||
{
|
||||
startingKeyFrame = static_cast<int>(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
skinningMatrices.resize(startBones.size());
|
||||
|
||||
if (startingKeyFrame == -1)
|
||||
{
|
||||
for (auto& m : skinningMatrices) m = Matrix4f::Identity();
|
||||
return;
|
||||
}
|
||||
|
||||
int modifiedFrameNumber = frame - keyFrames[startingKeyFrame].frame;
|
||||
int diffFrames = keyFrames[startingKeyFrame + 1].frame - keyFrames[startingKeyFrame].frame;
|
||||
float t = (modifiedFrameNumber + 0.f) / diffFrames;
|
||||
|
||||
const std::vector<Bone>& oneFrameBones = keyFrames[startingKeyFrame].bones;
|
||||
const std::vector<Bone>& nextFrameBones = keyFrames[startingKeyFrame + 1].bones;
|
||||
|
||||
for (size_t i = 0; i < startBones.size(); i++)
|
||||
{
|
||||
Vector3f interpPos;
|
||||
interpPos(0) = oneFrameBones[i].boneStartWorld(0) + t * (nextFrameBones[i].boneStartWorld(0) - oneFrameBones[i].boneStartWorld(0));
|
||||
interpPos(1) = oneFrameBones[i].boneStartWorld(1) + t * (nextFrameBones[i].boneStartWorld(1) - oneFrameBones[i].boneStartWorld(1));
|
||||
interpPos(2) = oneFrameBones[i].boneStartWorld(2) + t * (nextFrameBones[i].boneStartWorld(2) - oneFrameBones[i].boneStartWorld(2));
|
||||
|
||||
Matrix3f oneFrameBonesMatrix = oneFrameBones[i].boneMatrixWorld.block<3, 3>(0, 0);
|
||||
Matrix3f nextFrameBonesMatrix = nextFrameBones[i].boneMatrixWorld.block<3, 3>(0, 0);
|
||||
|
||||
Eigen::Quaternionf q1 = Eigen::Quaternionf(oneFrameBonesMatrix).normalized();
|
||||
Eigen::Quaternionf q2 = Eigen::Quaternionf(nextFrameBonesMatrix).normalized();
|
||||
Eigen::Quaternionf result = q1.slerp(t, q2);
|
||||
|
||||
Matrix3f boneMatrixWorld3 = result.toRotationMatrix();
|
||||
|
||||
Matrix4f currentBoneMatrixWorld4 = Eigen::Matrix4f::Identity();
|
||||
currentBoneMatrixWorld4.block<3, 3>(0, 0) = boneMatrixWorld3;
|
||||
currentBoneMatrixWorld4.block<3, 1>(0, 3) = interpPos;
|
||||
|
||||
Matrix4f startBoneMatrixWorld4 = keyFrames[0].bones[i].boneMatrixWorld;
|
||||
skinningMatrices[i] = currentBoneMatrixWorld4 * startBoneMatrixWorld4.inverse();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
#pragma once
|
||||
#include "BoneAnimatedModel.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace ZL
|
||||
{
|
||||
struct MeshBoneData
|
||||
{
|
||||
VertexDataStruct mesh;
|
||||
VertexDataStruct startMesh;
|
||||
std::vector<std::array<BoneWeight, MAX_BONE_COUNT>> verticesBoneWeight;
|
||||
};
|
||||
|
||||
struct BoneSystemNew
|
||||
{
|
||||
std::unordered_map<std::string, MeshBoneData> meshes;
|
||||
std::vector<std::string> meshNamesOrdered;
|
||||
|
||||
Matrix4f armatureMatrix;
|
||||
|
||||
std::vector<Bone> startBones;
|
||||
std::vector<Bone> currentBones;
|
||||
|
||||
std::vector<Animation> animations;
|
||||
int startingFrame = 0;
|
||||
|
||||
void LoadFromFile(const std::string& fileName, const std::string& ZIPFileName = "");
|
||||
|
||||
void Interpolate(int frame);
|
||||
};
|
||||
|
||||
struct MeshGpuSkinningData
|
||||
{
|
||||
GpuBoneData gpuBoneData;
|
||||
|
||||
VertexRenderStruct bindPoseMutable;
|
||||
std::shared_ptr<VBOHolder> boneIndices0VBO;
|
||||
std::shared_ptr<VBOHolder> boneIndices1VBO;
|
||||
std::shared_ptr<VBOHolder> boneWeights0VBO;
|
||||
std::shared_ptr<VBOHolder> boneWeights1VBO;
|
||||
bool gpuSkinningPrepared = false;
|
||||
|
||||
void prepareGpuSkinningVBOs(MeshBoneData& meshData);
|
||||
void RenderVBO(Renderer& renderer);
|
||||
};
|
||||
|
||||
struct GpuSkinningShaderDataNew
|
||||
{
|
||||
std::unordered_map<std::string, MeshGpuSkinningData> perMesh;
|
||||
std::vector<Eigen::Matrix4f> skinningMatrices;
|
||||
|
||||
void prepareGpuSkinningVBOs(BoneSystemNew& model);
|
||||
void RenderVBO(Renderer& renderer, const std::vector<std::string>& meshNamesOrdered);
|
||||
void ComputeSkinningMatrices(const std::vector<Bone>& startBones, const std::vector<AnimationKeyFrame>& keyFrames, int frame);
|
||||
};
|
||||
|
||||
struct BoneAnimationDataNew
|
||||
{
|
||||
BoneSystemNew model;
|
||||
float currentFrame = 0.f;
|
||||
int lastFrame = -1;
|
||||
int totalFrames = 1;
|
||||
|
||||
GpuSkinningShaderDataNew gpuSkinningShaderData;
|
||||
};
|
||||
};
|
||||
@ -18,17 +18,14 @@ void Character::loadAnimation(AnimationState state, const std::string& filename,
|
||||
}
|
||||
}
|
||||
void Character::loadBinaryAnimation(AnimationState state, const std::string& filename, const std::string& zipFile) {
|
||||
|
||||
throw std::runtime_error("Not supported");
|
||||
|
||||
/*auto& data = animations[state];
|
||||
auto& data = animations[state];
|
||||
data.model.LoadFromBinaryFile(filename, zipFile);
|
||||
if (!data.model.animations.empty() && !data.model.animations[0].keyFrames.empty()) {
|
||||
data.totalFrames = data.model.animations[0].keyFrames.back().frame + 1;
|
||||
}
|
||||
else {
|
||||
data.totalFrames = 1;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void Character::setTarget(const Eigen::Vector3f& target,
|
||||
@ -275,7 +272,7 @@ void Character::draw(Renderer& renderer) {
|
||||
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || texturePerMesh.empty()) return;
|
||||
if (it == animations.end() || !texture) return;
|
||||
|
||||
renderer.shaderManager.PushShader(defaultShaderName);
|
||||
renderer.RenderUniform1i(textureUniformName, 0);
|
||||
@ -291,13 +288,10 @@ void Character::draw(Renderer& renderer) {
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
auto& anim = it->second;
|
||||
|
||||
for (const auto& [meshName, texture] : texturePerMesh) {
|
||||
modelMutableMap[meshName].AssignFrom(anim.model.meshes[meshName].mesh);
|
||||
modelMutableMap[meshName].RefreshVBO();
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(modelMutableMap[meshName]);
|
||||
}
|
||||
modelMutable.AssignFrom(anim.model.mesh);
|
||||
modelMutable.RefreshVBO();
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(modelMutable);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
@ -307,7 +301,7 @@ void Character::draw(Renderer& renderer) {
|
||||
void Character::drawGpuSkinning(Renderer& renderer) {
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || texturePerMesh.empty())
|
||||
if (it == animations.end() || !texture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -344,26 +338,19 @@ void Character::drawGpuSkinning(Renderer& renderer) {
|
||||
static_cast<int>(anim.gpuSkinningShaderData.skinningMatrices.size()), false,
|
||||
anim.gpuSkinningShaderData.skinningMatrices[0].data());
|
||||
|
||||
for (const auto& meshName : anim.model.meshNamesOrdered) {
|
||||
auto texIt = texturePerMesh.find(meshName);
|
||||
if (texIt == texturePerMesh.end()) continue;
|
||||
|
||||
auto meshIt = anim.gpuSkinningShaderData.perMesh.find(meshName);
|
||||
if (meshIt == anim.gpuSkinningShaderData.perMesh.end()) continue;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texIt->second->getTexID());
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
|
||||
// Bind VAO (desktop only)
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (meshIt->second.bindPoseMutable.vao) {
|
||||
glBindVertexArray(meshIt->second.bindPoseMutable.vao->getBuffer());
|
||||
renderer.shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
if (anim.gpuSkinningShaderData.bindPoseMutable.vao) {
|
||||
glBindVertexArray(anim.gpuSkinningShaderData.bindPoseMutable.vao->getBuffer());
|
||||
renderer.shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
meshIt->second.RenderVBO(renderer);
|
||||
}
|
||||
anim.gpuSkinningShaderData.RenderVBO(renderer);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
@ -409,7 +396,6 @@ void Character::drawShadowDepth(Renderer& renderer) {
|
||||
}
|
||||
|
||||
void Character::drawShadowDepthCpu(Renderer& renderer) {
|
||||
/*
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end()) return;
|
||||
@ -427,14 +413,11 @@ void Character::drawShadowDepthCpu(Renderer& renderer) {
|
||||
modelMutable.RefreshVBO();
|
||||
renderer.DrawVertexRenderStruct(modelMutable);
|
||||
|
||||
renderer.PopMatrix();*/
|
||||
std::cout << "CPU skinning shadow depth rendering is not implemented." << std::endl;
|
||||
throw std::runtime_error("Not supported");
|
||||
renderer.PopMatrix();
|
||||
}
|
||||
|
||||
void Character::drawShadowDepthGpuSkinning(Renderer& renderer) {
|
||||
|
||||
/*
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
@ -470,9 +453,7 @@ void Character::drawShadowDepthGpuSkinning(Renderer& renderer) {
|
||||
renderer.PopMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
|
||||
CheckGlError(__FILE__, __LINE__);*/
|
||||
std::cout << "CPU skinning shadow depth rendering is not implemented." << std::endl;
|
||||
throw std::runtime_error("Not supported");
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// ==================== Main pass with shadows ====================
|
||||
@ -486,7 +467,7 @@ void Character::drawWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightF
|
||||
}
|
||||
|
||||
void Character::drawCpuWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera) {
|
||||
/*AnimationState drawState = resolveActiveState();
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || !texture) return;
|
||||
|
||||
@ -520,13 +501,11 @@ void Character::drawCpuWithShadow(Renderer& renderer, const Eigen::Matrix4f& lig
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
renderer.shaderManager.PopShader();*/
|
||||
std::cout << "CPU skinning shadow depth rendering is not implemented." << std::endl;
|
||||
throw std::runtime_error("Not supported");
|
||||
renderer.shaderManager.PopShader();
|
||||
}
|
||||
|
||||
void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera) {
|
||||
/*AnimationState drawState = resolveActiveState();
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || !texture) return;
|
||||
|
||||
@ -580,9 +559,7 @@ void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matri
|
||||
renderer.PopProjectionMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
|
||||
CheckGlError(__FILE__, __LINE__);*/
|
||||
std::cout << "CPU skinning shadow depth rendering is not implemented." << std::endl;
|
||||
throw std::runtime_error("Not supported");
|
||||
CheckGlError(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
} // namespace ZL
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
#include "BoneAnimatedModel.h"
|
||||
|
||||
#include "BoneAnimatedModelNew.h"
|
||||
#include "render/Renderer.h"
|
||||
#include "render/TextureManager.h"
|
||||
#include "items/Item.h"
|
||||
@ -32,8 +30,8 @@ public:
|
||||
void loadAnimation(AnimationState state, const std::string& filename, const std::string& zipFile = "");
|
||||
void loadBinaryAnimation(AnimationState state, const std::string& filename, const std::string& zipFile = "");
|
||||
|
||||
void setTexture(const std::string& meshName, std::shared_ptr<Texture> texture) {
|
||||
texturePerMesh[meshName] = texture;
|
||||
void setTexture(std::shared_ptr<Texture> texture) {
|
||||
this->texture = texture;
|
||||
}
|
||||
void update(int64_t deltaMs);
|
||||
// onArrived is called once when the character reaches this target.
|
||||
@ -80,9 +78,9 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
std::map<AnimationState, BoneAnimationDataNew> animations;
|
||||
std::map<std::string, VertexRenderStruct> modelMutableMap;
|
||||
std::map<std::string, std::shared_ptr<Texture>> texturePerMesh;
|
||||
std::map<AnimationState, BoneAnimationData> animations;
|
||||
VertexRenderStruct modelMutable;
|
||||
std::shared_ptr<Texture> texture;
|
||||
|
||||
Eigen::Vector3f walkTarget = Eigen::Vector3f(0.f, 0.f, 0.f);
|
||||
Eigen::Vector3f requestedWalkTarget = Eigen::Vector3f(0.f, 0.f, 0.f);
|
||||
|
||||
313
src/Location.cpp
313
src/Location.cpp
@ -30,58 +30,199 @@ namespace ZL
|
||||
|
||||
}
|
||||
|
||||
/*void Location::setup()
|
||||
{
|
||||
roomTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/room005.png", CONST_ZIP_FILE));
|
||||
roomMesh.data = LoadFromTextFile02("resources/w/room001.txt", CONST_ZIP_FILE);
|
||||
roomMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
roomMesh.RefreshVBO();
|
||||
|
||||
carTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/e/car002.png", CONST_ZIP_FILE));
|
||||
carMesh.data = LoadFromTextFile02("resources/e/car001.txt", CONST_ZIP_FILE);
|
||||
//carMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
carMesh.RefreshVBO();
|
||||
|
||||
|
||||
// Load static game objects
|
||||
gameObjects = GameObjectLoader::loadAndCreateGameObjects("resources/config2/gameobjects.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
// Load interactive objects
|
||||
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects("resources/config2/gameobjects.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
|
||||
auto playerTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/gg/IMG_20260413_182354_992.png", CONST_ZIP_FILE));
|
||||
|
||||
player = std::make_unique<Character>();
|
||||
|
||||
player->loadBinaryAnimation(AnimationState::STAND, "resources/w/gg/gg_stand_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::WALK, "resources/w/gg/gg_walking001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::STAND_TO_ACTION, "resources/w/gg/gg_stand_to_action002.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_ATTACK, "resources/w/gg/gg_action_attack001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_IDLE, "resources/w/gg/gg_action_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/gg/gg_action_to_stand001.anim", CONST_ZIP_FILE);
|
||||
|
||||
player->setTexture(playerTexture);
|
||||
player->walkSpeed = 3.0f;
|
||||
player->rotationSpeed = 8.0f;
|
||||
|
||||
player->modelScale = 1.f;
|
||||
player->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
|
||||
player->canAttack = true;
|
||||
player->isPlayer = true;
|
||||
std::cout << "Load resurces step 9" << std::endl;
|
||||
|
||||
// Load NPCs from JSON
|
||||
npcs = GameObjectLoader::loadAndCreateNpcs("resources/config2/npcs.json", CONST_ZIP_FILE);
|
||||
|
||||
auto ghostTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/ghost_skin001.png", CONST_ZIP_FILE));
|
||||
|
||||
std::cout << "Load resurces step 11" << std::endl;
|
||||
auto npc02 = std::make_unique<Character>();
|
||||
|
||||
npc02->loadBinaryAnimation(AnimationState::STAND, "resources/w/default_float001.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::WALK, "resources/w/default_float001.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::ACTION_IDLE, "resources/w/float_attack003_cut.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::ACTION_ATTACK, "resources/w/float_attack003.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::STAND_TO_ACTION, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
|
||||
npc02->setTexture(ghostTexture);
|
||||
npc02->walkSpeed = 1.5f;
|
||||
npc02->rotationSpeed = 8.0f;
|
||||
npc02->modelScale = 0.01f;
|
||||
//npc02->modelScale = 0.1f;
|
||||
npc02->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
|
||||
npc02->position = Eigen::Vector3f(0.f, 0.f, -20.f);
|
||||
npc02->setTarget(npc02->position);
|
||||
npc02->canAttack = true;
|
||||
npc02->attackTarget = player.get();
|
||||
|
||||
npcs.push_back(std::move(npc02));
|
||||
|
||||
// Create shadow map (2048x2048, ortho size 40, near 0.1, far 100)
|
||||
shadowMap = std::make_unique<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
||||
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
||||
std::cout << "Shadow map initialized" << std::endl;
|
||||
|
||||
setupNavigation();
|
||||
|
||||
scriptEngine.init(this, &inventory);
|
||||
|
||||
|
||||
dialogueSystem.init(renderer, CONST_ZIP_FILE);
|
||||
dialogueSystem.loadDatabase("resources/dialogue/sample_dialogues.json");
|
||||
/*dialogueSystem.addTriggerZone({
|
||||
"ghost_room_trigger",
|
||||
"test_line_dialogue",
|
||||
Eigen::Vector3f(0.0f, 0.0f, -8.5f),
|
||||
2.0f,
|
||||
true,
|
||||
false
|
||||
});
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
/*void Location::setup()
|
||||
{
|
||||
std::string roomTexPath;
|
||||
std::string roomMeshPath;
|
||||
std::string gameObjectsPath;
|
||||
std::string interactiveObjectsPath;
|
||||
std::string npcsPath;
|
||||
|
||||
if (locationId == "forest")
|
||||
{
|
||||
std::cout << "[LOCATION] Setting up FOREST location (using placeholder resources)" << std::endl;
|
||||
roomTexPath = "resources/w/room005.png";
|
||||
roomMeshPath = "resources/w/room001.txt";
|
||||
gameObjectsPath = "resources/config2/gameobjects2.json";
|
||||
interactiveObjectsPath = "resources/config2/gameobjects2.json";
|
||||
npcsPath = "resources/config2/npcs2.json";
|
||||
}
|
||||
else // default
|
||||
{
|
||||
std::cout << "[LOCATION] Setting up DEFAULT location" << std::endl;
|
||||
roomTexPath = "resources/w/room005.png";
|
||||
roomMeshPath = "resources/w/room001.txt";
|
||||
gameObjectsPath = "resources/config2/gameobjects.json";
|
||||
interactiveObjectsPath = "resources/config2/gameobjects.json";
|
||||
npcsPath = "resources/config2/npcs.json";
|
||||
}
|
||||
|
||||
roomTexture = std::make_unique<Texture>(CreateTextureDataFromPng(roomTexPath.c_str(), CONST_ZIP_FILE));
|
||||
roomMesh.data = LoadFromTextFile02(roomMeshPath.c_str(), CONST_ZIP_FILE);
|
||||
roomMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
roomMesh.RefreshVBO();
|
||||
|
||||
carTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/e/car002.png", CONST_ZIP_FILE));
|
||||
carMesh.data = LoadFromTextFile02("resources/e/car001.txt", CONST_ZIP_FILE);
|
||||
carMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
carMesh.RefreshVBO();
|
||||
|
||||
carWheelTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/e/Wheel_base002.png", CONST_ZIP_FILE));
|
||||
carWheelMesh.data = LoadFromTextFile02("resources/e/car_wheel001.txt", CONST_ZIP_FILE);
|
||||
carWheelMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
carWheelMesh.RefreshVBO();
|
||||
|
||||
gameObjects = GameObjectLoader::loadAndCreateGameObjects(gameObjectsPath, renderer, CONST_ZIP_FILE);
|
||||
|
||||
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects(interactiveObjectsPath, renderer, CONST_ZIP_FILE);
|
||||
|
||||
auto playerTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/gg/IMG_20260413_182354_992.png", CONST_ZIP_FILE));
|
||||
player = std::make_unique<Character>();
|
||||
player->loadBinaryAnimation(AnimationState::STAND, "resources/w/gg/gg_stand_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::WALK, "resources/w/gg/gg_walking001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::STAND_TO_ACTION, "resources/w/gg/gg_stand_to_action002.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_ATTACK, "resources/w/gg/gg_action_attack001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_IDLE, "resources/w/gg/gg_action_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/gg/gg_action_to_stand001.anim", CONST_ZIP_FILE);
|
||||
player->setTexture(playerTexture);
|
||||
player->walkSpeed = 3.0f;
|
||||
player->rotationSpeed = 8.0f;
|
||||
player->modelScale = 1.f;
|
||||
player->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
player->canAttack = true;
|
||||
player->isPlayer = true;
|
||||
std::cout << "Load resources step 9" << std::endl;
|
||||
|
||||
npcs = GameObjectLoader::loadAndCreateNpcs(npcsPath, CONST_ZIP_FILE);
|
||||
|
||||
auto ghostTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/ghost_skin001.png", CONST_ZIP_FILE));
|
||||
std::cout << "Load resources step 11" << std::endl;
|
||||
auto npc02 = std::make_unique<Character>();
|
||||
npc02->loadBinaryAnimation(AnimationState::STAND, "resources/w/default_float001.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::WALK, "resources/w/default_float001.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::ACTION_IDLE, "resources/w/float_attack003_cut.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::ACTION_ATTACK, "resources/w/float_attack003.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::STAND_TO_ACTION, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
|
||||
npc02->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
|
||||
npc02->setTexture(ghostTexture);
|
||||
npc02->walkSpeed = 1.5f;
|
||||
npc02->rotationSpeed = 8.0f;
|
||||
npc02->modelScale = 0.01f;
|
||||
npc02->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
npc02->position = Eigen::Vector3f(0.f, 0.f, -20.f);
|
||||
npc02->setTarget(npc02->position);
|
||||
npc02->canAttack = true;
|
||||
npc02->attackTarget = player.get();
|
||||
npcs.push_back(std::move(npc02));
|
||||
|
||||
shadowMap = std::make_unique<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
||||
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
||||
std::cout << "Shadow map initialized" << std::endl;
|
||||
|
||||
setupNavigation();
|
||||
|
||||
scriptEngine.init(this, &inventory);
|
||||
|
||||
dialogueSystem.init(renderer, CONST_ZIP_FILE);
|
||||
dialogueSystem.loadDatabase("resources/dialogue/sample_dialogues.json");
|
||||
}*/
|
||||
|
||||
void Location::setup()
|
||||
{
|
||||
auto playerTexture0 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/male_packed0_diffuse.png", CONST_ZIP_FILE));
|
||||
auto playerTexture1 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/male_packed1_diffuse.png", CONST_ZIP_FILE));
|
||||
auto playerTexture2 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/male_packed2_diffuse.png", CONST_ZIP_FILE));
|
||||
|
||||
player = std::make_unique<Character>();
|
||||
player->loadAnimation(AnimationState::STAND, "resources/e/gg_stand_idle003.txt", CONST_ZIP_FILE);
|
||||
player->loadAnimation(AnimationState::WALK, "resources/e/gg_stand_idle003.txt", CONST_ZIP_FILE);
|
||||
player->setTexture("Body", playerTexture0);
|
||||
player->setTexture("Bottoms", playerTexture1);
|
||||
player->setTexture("Eyelashes", playerTexture0);
|
||||
player->setTexture("Eyes", playerTexture0);
|
||||
player->setTexture("Eyewear", playerTexture0);
|
||||
player->setTexture("Gloves", playerTexture1);
|
||||
player->setTexture("Hair", playerTexture0);
|
||||
player->setTexture("Shoes", playerTexture1);
|
||||
player->setTexture("Tops", playerTexture1);
|
||||
player->walkSpeed = 3.0f;
|
||||
player->rotationSpeed = 8.0f;
|
||||
player->modelScale = 0.01f;
|
||||
player->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
player->canAttack = true;
|
||||
player->isPlayer = true;
|
||||
|
||||
|
||||
auto girlfriendTexture0 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/female_packed0_diffuse.png", CONST_ZIP_FILE));
|
||||
auto girlfriendTexture1 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/female_packed1_diffuse.png", CONST_ZIP_FILE));
|
||||
auto girlfriendTexture2 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/female_packed2_diffuse.png", CONST_ZIP_FILE));
|
||||
auto girlfriendTexture3 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/female_packed3_diffuse.png", CONST_ZIP_FILE));
|
||||
|
||||
girlfriend = std::make_unique<Character>();
|
||||
girlfriend->loadAnimation(AnimationState::STAND, "resources/e/woman_stand_idle003.txt", CONST_ZIP_FILE);
|
||||
girlfriend->loadAnimation(AnimationState::WALK, "resources/e/woman_stand_idle003.txt", CONST_ZIP_FILE);
|
||||
girlfriend->setTexture("Body", girlfriendTexture0);
|
||||
girlfriend->setTexture("Bottoms", girlfriendTexture3);
|
||||
girlfriend->setTexture("Eyelashes", girlfriendTexture0);
|
||||
girlfriend->setTexture("Eyes", girlfriendTexture0);
|
||||
girlfriend->setTexture("Hair", girlfriendTexture2);
|
||||
girlfriend->setTexture("Shoes", girlfriendTexture1);
|
||||
girlfriend->setTexture("Tops", girlfriendTexture2);
|
||||
girlfriend->walkSpeed = 3.0f;
|
||||
girlfriend->rotationSpeed = 8.0f;
|
||||
girlfriend->modelScale = 0.01f;
|
||||
girlfriend->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
girlfriend->position = Vector3f{ -10, -0, -10 };
|
||||
girlfriend->setTarget(girlfriend->position);
|
||||
|
||||
|
||||
//girlfriend->canAttack = true;
|
||||
//player->isPlayer = true;
|
||||
|
||||
if (locationId == "forest")
|
||||
{
|
||||
std::cout << "[LOCATION] Setting up FOREST location (custom models only)" << std::endl;
|
||||
@ -132,6 +273,21 @@ void Location::setup()
|
||||
}
|
||||
}
|
||||
|
||||
auto playerTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/gg/IMG_20260413_182354_992.png", CONST_ZIP_FILE));
|
||||
player = std::make_unique<Character>();
|
||||
player->loadBinaryAnimation(AnimationState::STAND, "resources/w/gg/gg_stand_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::WALK, "resources/w/gg/gg_walking001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::STAND_TO_ACTION, "resources/w/gg/gg_stand_to_action002.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_ATTACK, "resources/w/gg/gg_action_attack001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_IDLE, "resources/w/gg/gg_action_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/gg/gg_action_to_stand001.anim", CONST_ZIP_FILE);
|
||||
player->setTexture(playerTexture);
|
||||
player->walkSpeed = 3.0f;
|
||||
player->rotationSpeed = 8.0f;
|
||||
player->modelScale = 1.f;
|
||||
player->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
player->canAttack = true;
|
||||
player->isPlayer = true;
|
||||
|
||||
shadowMap = std::make_unique<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
||||
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
||||
@ -161,26 +317,23 @@ void Location::setup()
|
||||
gameObjects = GameObjectLoader::loadAndCreateGameObjects(gameObjectsPath, renderer, CONST_ZIP_FILE);
|
||||
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects(interactiveObjectsPath, renderer, CONST_ZIP_FILE);
|
||||
npcs = GameObjectLoader::loadAndCreateNpcs(npcsPath, CONST_ZIP_FILE);
|
||||
/*
|
||||
|
||||
auto playerTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/gg/IMG_20260413_182354_992.png", CONST_ZIP_FILE));
|
||||
player = std::make_unique<Character>();
|
||||
player->loadAnimation(AnimationState::STAND, "resources/e/woman_stand_idle003.txt", CONST_ZIP_FILE);
|
||||
player->loadAnimation(AnimationState::WALK, "resources/e/woman_stand_idle003.txt", CONST_ZIP_FILE);
|
||||
player->setTexture("Body", playerTexture1);
|
||||
player->setTexture("Bottoms", playerTexture4);
|
||||
player->setTexture("Eyelashes", playerTexture1);
|
||||
player->setTexture("Eyes", playerTexture1);
|
||||
player->setTexture("Hair", playerTexture3);
|
||||
player->setTexture("Shoes", playerTexture1);
|
||||
player->setTexture("Tops", playerTexture3);
|
||||
player->loadBinaryAnimation(AnimationState::STAND, "resources/w/gg/gg_stand_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::WALK, "resources/w/gg/gg_walking001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::STAND_TO_ACTION, "resources/w/gg/gg_stand_to_action002.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_ATTACK, "resources/w/gg/gg_action_attack001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_IDLE, "resources/w/gg/gg_action_idle001.anim", CONST_ZIP_FILE);
|
||||
player->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/gg/gg_action_to_stand001.anim", CONST_ZIP_FILE);
|
||||
player->setTexture(playerTexture);
|
||||
player->walkSpeed = 3.0f;
|
||||
player->rotationSpeed = 8.0f;
|
||||
player->modelScale = 0.01f;
|
||||
player->modelScale = 1.f;
|
||||
player->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
player->canAttack = true;
|
||||
player->isPlayer = true;
|
||||
*/
|
||||
/*
|
||||
|
||||
auto ghostTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/ghost_skin001.png", CONST_ZIP_FILE));
|
||||
auto npc02 = std::make_unique<Character>();
|
||||
npc02->loadBinaryAnimation(AnimationState::STAND, "resources/w/default_float001.anim", CONST_ZIP_FILE);
|
||||
@ -199,7 +352,7 @@ void Location::setup()
|
||||
npc02->canAttack = true;
|
||||
npc02->attackTarget = player.get();
|
||||
npcs.push_back(std::move(npc02));
|
||||
*/
|
||||
|
||||
shadowMap = std::make_unique<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
||||
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
||||
|
||||
@ -219,20 +372,6 @@ void Location::setup()
|
||||
carWheelMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
carWheelMesh.RefreshVBO();
|
||||
|
||||
/*
|
||||
auto girlfriendTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/female_packed0_diffuse.png", CONST_ZIP_FILE));
|
||||
girlfriend = std::make_unique<Character>();
|
||||
girlfriend->loadAnimation(AnimationState::STAND, "resources/e/woman_stand_idle001.txt", CONST_ZIP_FILE);
|
||||
girlfriend->loadAnimation(AnimationState::WALK, "resources/e/woman_run001.txt", CONST_ZIP_FILE);
|
||||
girlfriend->setTexture(girlfriendTexture);
|
||||
girlfriend->walkSpeed = 3.0f;
|
||||
girlfriend->rotationSpeed = 8.0f;
|
||||
girlfriend->modelScale = 0.01f;
|
||||
girlfriend->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||
girlfriend->position = Vector3f{ -10, -0, -10 };
|
||||
girlfriend->setTarget(girlfriend->position);*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Location::setupNavigation()
|
||||
@ -466,12 +605,6 @@ void Location::setup()
|
||||
renderer.PopMatrix();
|
||||
|
||||
if (player && !inCar) player->draw(renderer);
|
||||
|
||||
if (girlfriend)
|
||||
{
|
||||
girlfriend->draw(renderer);
|
||||
}
|
||||
|
||||
for (auto& npc : npcs) npc->draw(renderer);
|
||||
|
||||
//#ifdef SHOW_PATH
|
||||
@ -548,12 +681,6 @@ void Location::setup()
|
||||
|
||||
// Draw characters (they handle their own skinning shader switch internally)
|
||||
if (player) player->drawShadowDepth(renderer);
|
||||
|
||||
if (girlfriend)
|
||||
{
|
||||
girlfriend->drawShadowDepth(renderer);
|
||||
}
|
||||
|
||||
for (auto& npc : npcs) npc->drawShadowDepth(renderer);
|
||||
|
||||
renderer.PopMatrix(); // light view
|
||||
@ -687,12 +814,6 @@ void Location::setup()
|
||||
roofVisible = !(insideAnyZone && player->position.y() < maxHeightForHide);
|
||||
}
|
||||
}
|
||||
|
||||
if (girlfriend)
|
||||
{
|
||||
girlfriend->update(delta);
|
||||
}
|
||||
|
||||
for (auto& npc : npcs) npc->update(delta);
|
||||
|
||||
if (inCar) {
|
||||
|
||||
@ -28,8 +28,6 @@ namespace ZL
|
||||
|
||||
|
||||
std::unique_ptr<Character> player;
|
||||
std::unique_ptr<Character> girlfriend;
|
||||
|
||||
std::vector<std::unique_ptr<Character>> npcs;
|
||||
|
||||
float cameraAzimuth = 0.0f;
|
||||
|
||||
@ -382,7 +382,6 @@ namespace ZL {
|
||||
const std::string& jsonPath,
|
||||
const std::string& zipPath)
|
||||
{
|
||||
/*
|
||||
std::vector<std::unique_ptr<Character>> npcs;
|
||||
std::vector<NpcData> npcsData = loadNpcsFromJson(jsonPath, zipPath);
|
||||
|
||||
@ -475,8 +474,7 @@ namespace ZL {
|
||||
}
|
||||
|
||||
std::cout << "Total NPCs loaded: " << npcs.size() << std::endl;
|
||||
return npcs;*/
|
||||
return {};
|
||||
return npcs;
|
||||
}
|
||||
|
||||
} // namespace ZL
|
||||
Loading…
Reference in New Issue
Block a user