From 5aa2a9bdb53859d10cc28e55835a622d279ba6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Sobczy=C5=84ski?= Date: Mon, 2 Nov 2020 23:09:55 +0100 Subject: [PATCH] optimized rendering, fixed dff --- src/engine/include/loaders/dff_loader.hpp | 22 +- src/engine/include/loaders/dff_structure.hpp | 88 ++-- src/engine/include/models/mesh.hpp | 64 ++- src/engine/loaders/bmp_loader.cpp | 3 +- src/engine/loaders/dff_loader.cpp | 428 +++++++++---------- src/engine/models/mesh.cpp | 160 +++---- src/engine/modules/gif_sender.cpp | 2 +- src/engine/modules/renderer.cpp | 19 +- src/engine/modules/texture_repository.cpp | 2 +- src/samples/ari/ari.cpp | 101 ++--- src/samples/ari/objects/player.cpp | 14 +- src/samples/floors/objects/player.cpp | 32 ++ 12 files changed, 466 insertions(+), 469 deletions(-) diff --git a/src/engine/include/loaders/dff_loader.hpp b/src/engine/include/loaders/dff_loader.hpp index 20ea051..a9a6216 100644 --- a/src/engine/include/loaders/dff_loader.hpp +++ b/src/engine/include/loaders/dff_loader.hpp @@ -23,30 +23,26 @@ public: ~DffLoader(); void load(MeshFrame *o_result, char *t_fileName, float t_scale, u8 t_invertT); - void serialize(RwClump &t_clump, u8 *t_data, float t_scale); - - static u8 readByteFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); - static u16 readWordFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); - static u32 readDwordFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); - static float readFloatFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); - static u8 *readData(u8 *t_buffer, u32 &t_ptrPos, u32 t_dataSize); - static char *readString(u8 *t_buffer, u32 &t_ptrPos, u32 t_dataSize = 0); - - void readSectionHeader(RwSectionHeader &t_sh, u8 *t_buffer, u32 &t_ptrPos); + void serialize(MeshFrame *o_result, u8 t_invertT, u8 *t_data, float t_scale); private: - void convert(MeshFrame *frames, RwClump &t_clump, u8 t_invertT); // --- void readFrameListData(RwFrameListData &t_frd, u8 *t_buffer, u32 &t_ptrPos); void readClumpData(RwClumpData &t_cd, u8 *t_buffer, u32 &t_ptrPos); void readGeometryListData(RwGeometryListData &t_gld, u8 *t_buffer, u32 &t_ptrPos); - void readGeometryExtension(RwGeometryExtension &t_ge, u8 *t_buffer, u32 &t_ptrPos); - void readGeometryData(RwGeometryData &t_gd, u8 *t_buffer, u32 &t_ptrPos, float t_scale); + void readGeometryExtension(MeshFrame *o_frame, char **materialNames, u8 *t_buffer, u32 &t_ptrPos); + void readGeometryData(MeshFrame *o_frame, u8 t_invertT, u8 *t_buffer, u32 &t_ptrPos, float t_scale); void readMaterialListData(RwMaterialListData &t_mld, u8 *t_buffer, u32 &t_ptrPos); void readMaterialData(RwMaterialData &t_md, u8 *t_buffer, u32 &t_ptrPos); void readTextureData(RwTextureData &t_td, u8 *t_buffer, u32 &t_ptrPos); void readStringData(RwString &t_s, u8 *bt_uffer, u32 &t_ptrPos); + void readSectionHeader(RwSectionHeader &t_sh, u8 *t_buffer, u32 &t_ptrPos); // --- + u8 readByteFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); + u16 readWordFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); + u32 readDwordFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); + float readFloatFromArrayLE(u8 *t_buffer, u32 &t_ptrPos); + char *readString(u8 *t_buffer, u32 &t_ptrPos, u32 t_dataSize = 0); }; #endif diff --git a/src/engine/include/loaders/dff_structure.hpp b/src/engine/include/loaders/dff_structure.hpp index 96dcfe2..6c12b86 100644 --- a/src/engine/include/loaders/dff_structure.hpp +++ b/src/engine/include/loaders/dff_structure.hpp @@ -37,7 +37,7 @@ public: class RwFrameListChunk { public: - ~RwFrameListChunk() { delete[] rotationalMatrix; } + ~RwFrameListChunk() {} float *rotationalMatrix; // [ROT_MAT_DIM] float coordinatesOffsetX; float coordinatesOffsetY; @@ -50,7 +50,7 @@ public: class RwFrameListData : public RwSectionHeader { public: - ~RwFrameListData() { delete frameInformation; } + ~RwFrameListData() {} static const u32 ROT_MAT_DIM = 9; u32 frameCount; @@ -60,7 +60,7 @@ public: class RwFrame : public RwSectionHeader { public: - ~RwFrame() { delete[] frameName; } + ~RwFrame() {} u8 *frameName; // [sectionSize] - should be interpreted as string }; @@ -74,7 +74,7 @@ class RwFrameList : public RwSectionHeader { public: RwFrameListData data; - ~RwFrameList() { delete[] extensions; } + ~RwFrameList() {} RwFrameListExtension *extensions; }; // --- @@ -89,50 +89,65 @@ public: u32 morphTargetCount; }; -class RwGeometryDataLightingHeader +struct RwGeometryDataLightingHeader { // IF versionNumber = 4099 - according to not complete documentation -public: float ambient; float diffuse; float specular; }; -class RwGeometryDataColorInformationChunk +struct RwGeometryDataColorInformationChunk { // if rwOBJECT_VERTEX_PREILIT in flags -public: + u8 red; u8 green; u8 blue; u8 alpha; }; -class RwGeometryDataTextureMappingInformationChunk +struct RwGeometryDataTextureMappingInformationChunk { // if rwOBJECT_VERTEX_TEXTURED in flags -public: float u; float v; }; -class RwGeometryDataFaceInformation +struct RwGeometryDataFaceInformation { -public: u16 vertex2; // this u16 vertex1; // is u16 flags; // weird u16 vertex3; // order }; +class RwGeometryDataNonameInfo +{ +public: + float boundingSphereX; + float boundingSphereY; + float boundingSphereZ; + float boundingSphereR; + u32 hasPosition; + u32 hasNormals; +}; + +#include +#include + // Section: Geometry class RwGeometryData : public RwSectionHeader { public: ~RwGeometryData() { - delete colorInformation; - delete textureMappingInformation; - delete faceInformation; - delete vertexInformation; - delete normalInformation; + // if (dataHeader.flags & rwOBJECT_VERTEX_NORMALS) + // delete[] normalInformation; + // delete[] vertexInformation; + // free(vertexInformation); + // delete[] faceInformation; + // if (dataHeader.flags & rwOBJECT_VERTEX_PRELIT) + // delete[] colorInformation; + // if (dataHeader.flags & rwOBJECT_VERTEX_TEXTURED) + // delete[] textureMappingInformation; } RwGeometryDataHeader dataHeader; @@ -144,16 +159,7 @@ public: RwGeometryDataFaceInformation *faceInformation; // [triangleCount] - class RwGeometryDataNonameInfo - { - public: - float boundingSphereX; - float boundingSphereY; - float boundingSphereZ; - float boundingSphereR; - u32 hasPosition; - u32 hasNormals; - } nonameInfo; + RwGeometryDataNonameInfo nonameInfo; Vector3 *vertexInformation; // [vertexCount] @@ -211,7 +217,7 @@ class RwMaterialExtension : public RwSectionHeader class RwMaterial : public RwSectionHeader { public: - ~RwMaterial() { delete[] textures; } + ~RwMaterial() {} RwMaterialData data; RwTexture *textures; RwMaterialExtension extension; @@ -220,7 +226,7 @@ public: class RwMaterialListData : public RwSectionHeader { public: - ~RwMaterialListData() { delete[] arrayOfUnks; } + ~RwMaterialListData() {} u32 materialCount; u32 *arrayOfUnks; // Filled with '-1's, [materialCount] - it wasn't mentioned in docs. }; @@ -228,7 +234,7 @@ public: class RwMaterialList : public RwSectionHeader { public: - ~RwMaterialList() { delete[] materials; } + ~RwMaterialList() {} RwMaterialListData data; RwMaterial *materials; }; @@ -242,24 +248,26 @@ public: class RwGeometryListInfoChunk { public: - ~RwGeometryListInfoChunk() { delete vertexInformation; } + ~RwGeometryListInfoChunk() {} u32 faceIndex; u32 materialIndex; RwGeometryListVertexInfoChunk *vertexInformation; // [faceIndex] }; +class RwMaterialSplitHeader +{ +public: + u32 triangleStrip; + u32 splitCount; + u32 faceCount; +}; + class RwMaterialSplit { public: - ~RwMaterialSplit() { delete splitInformation; } - class Header - { - public: - u32 triangleStrip; - u32 splitCount; - u32 faceCount; - } header; + ~RwMaterialSplit() {} + RwMaterialSplitHeader header; RwGeometryListInfoChunk *splitInformation; // [splitCount] }; @@ -289,7 +297,7 @@ public: class RwGeometryList : public RwSectionHeader { public: - ~RwGeometryList() { delete[] geometries; } + ~RwGeometryList() {} RwGeometryListData data; RwGeometry *geometries; }; diff --git a/src/engine/include/models/mesh.hpp b/src/engine/include/models/mesh.hpp index af9e876..336533e 100644 --- a/src/engine/include/models/mesh.hpp +++ b/src/engine/include/models/mesh.hpp @@ -33,11 +33,16 @@ public: float scale; u8 shouldBeLighted, shouldBeBackfaceCulled, shouldBeFrustumCulled; color_t color; + clutbuffer_t clut; + lod_t lod; // ---- // Getters // ---- + /** Auto generated unique Id. */ + const u32 &getId() const { return id; }; + /** Array of materials. Size of getMaterialsCount() */ MeshMaterial *getMaterials() const { return frames[0].getMaterials(); }; @@ -46,6 +51,28 @@ public: /** Returns material, which is a mesh "subgroup". */ MeshMaterial &getMaterial(const u32 &i) const { return frames[0].getMaterial(i); }; + /** Auto count of frames. Static object (not animated) will have only 1 frame. */ + const u32 &getFramesCount() const { return framesCount; }; + + /** Count of vertices. */ + u32 getVertexCount() { return frames[0].getVertexCount(); }; + + /** Returns single frame. */ + MeshFrame &getFrame(const u32 &i) const { return frames[i]; }; + + /** Array of frames. Size of getFramesCount() */ + MeshFrame *getFrames() const { return frames; }; + + const u32 &getCurrentAnimationFrame() const { return animState.currentFrame; }; + + const u32 &getNextAnimationFrame() const { return animState.nextFrame; }; + + const u32 &getStartAnimationFrame() const { return animState.startFrame; }; + + const u32 &getEndAnimationFrame() const { return animState.endFrame; }; + + const u32 &getStayAnimationFrame() const { return animState.stayFrame; }; + /** * Returns material, which is a mesh "subgroup". * NULL if not found. @@ -130,38 +157,43 @@ public: /** Play animation from startFrame to endFrame and after loop in stayFrame */ void playAnimation(const u32 &t_startFrame, const u32 &t_endFrame, const u32 &t_stayFrame); + void setAnimSpeed(const float &t_value) { animState.speed = t_value; } + /** * Check if this class loaded mesh data first. * Meshes which use loadFrom() method have false there. */ const u8 &isMother() const { return _isMother; }; - // TODO + /** + * Check if this class loaded mesh data first. + * Meshes which use loadFrom() method have false there. + */ + const u8 &isStayAnimationSet() const { return animState.isStayFrameSet; }; - // void getMinMax(Vector3 *t_min, Vector3 *t_max); - u32 getVertexCount(); - void setAnimSpeed(float t_value); + /** Check if mesh is visible in view frustum */ u8 isInFrustum(Plane *t_frustumPlanes); - clutbuffer_t clut; - lod_t lod; - u32 id; - - // NOWE TODO - - u32 framesCount; - MeshFrame *frames; - AnimState animState; + /** + * Do not call this method unless you know what you do. + * Should be called by renderer. + */ void animate(); + + /** + * Do not call this method unless you know what you do. + * Should be called by renderer. + */ u32 getDrawData(u32 t_materialIndex, VECTOR *o_vertices, VECTOR *o_normals, VECTOR *o_coordinates, Vector3 &t_cameraPos); - u32 getFacesCount(); - u8 isMemoryAllocated; private: + AnimState animState; + MeshFrame *frames; + u32 id, framesCount; u8 _isMother; Vector3 calc3Vectors[3]; - void setupLodAndClut(); void setDefaultColor(); + void setDefaultLODAndClut(); }; #endif diff --git a/src/engine/loaders/bmp_loader.cpp b/src/engine/loaders/bmp_loader.cpp index 008708b..4c8075f 100644 --- a/src/engine/loaders/bmp_loader.cpp +++ b/src/engine/loaders/bmp_loader.cpp @@ -32,7 +32,6 @@ BmpLoader::~BmpLoader() {} */ void BmpLoader::load(MeshTexture &o_texture, char *t_subfolder, char *t_name, char *t_extension) { - char *t_path_part = String::createConcatenated(t_subfolder, t_name); char *t_path = String::createConcatenated(t_path_part, t_extension); delete[] t_path_part; @@ -78,5 +77,5 @@ void BmpLoader::load(MeshTexture &o_texture, char *t_subfolder, char *t_name, ch } delete[] t_path; delete[] data; - // fclose(file); // wtf? + fclose(file); } diff --git a/src/engine/loaders/dff_loader.cpp b/src/engine/loaders/dff_loader.cpp index d57c62c..7fc0b2f 100644 --- a/src/engine/loaders/dff_loader.cpp +++ b/src/engine/loaders/dff_loader.cpp @@ -42,143 +42,128 @@ void DffLoader::load(MeshFrame *o_result, char *t_filename, float t_scale, u8 t_ PRINT_ERR("Failed to load .obj file!"); fseek(file, 0L, SEEK_END); long fileSize = ftell(file); - u8 *data = new u8[fileSize]; + u8 data[fileSize]; rewind(file); - fread(data, sizeof(u8), fileSize, file); + fread(&data, sizeof(u8), fileSize, file); fclose(file); - RwClump *clump = new RwClump(); - serialize(*clump, data, t_scale); - delete[] data; - // delete[] clump; // TODO - convert(o_result, *clump, t_invertT); + serialize(o_result, t_invertT, data, t_scale); + o_result->calculateBoundingBox(); PRINT_LOG("Dff file loaded!"); } -void DffLoader::convert(MeshFrame *o_result, RwClump &t_clump, u8 t_invertT) -{ -#define GEOMETRY t_clump.geometryList.geometries[0] - - MeshFrame *frame = &o_result[0]; - u32 vertNormalStCount = GEOMETRY.data.dataHeader.vertexCount; - frame->allocateVertices(vertNormalStCount); - frame->allocateNormals(vertNormalStCount); // can be optimized - frame->allocateSTs(vertNormalStCount); // can be optimized - - Vector3 tempVec = Vector3(); - Point tempPoint = Point(); - for (u32 i = 0; i < vertNormalStCount; i++) - { - tempVec.set( - GEOMETRY.data.vertexInformation[i].x, - GEOMETRY.data.vertexInformation[i].y, - GEOMETRY.data.vertexInformation[i].z); - frame->setVertex(i, tempVec); - tempVec.set( - GEOMETRY.data.normalInformation[i].x, - GEOMETRY.data.normalInformation[i].y, - GEOMETRY.data.normalInformation[i].z); - frame->setNormal(i, tempVec); - tempPoint.set( - GEOMETRY.data.textureMappingInformation[i].u, - GEOMETRY.data.textureMappingInformation[i].v); - if (t_invertT) - tempPoint.y = 1.0F - tempPoint.y; - frame->setST(i, tempPoint); - } - -#define CURR_SPLIT GEOMETRY.extension.materialSplit.splitInformation[i] - u32 materialsCount = GEOMETRY.extension.materialSplit.header.splitCount; - frame->allocateMaterials(materialsCount); - for (u32 i = 0; i < materialsCount; i++) - { - u32 facesCount = CURR_SPLIT.faceIndex; - u32 materialIndex = CURR_SPLIT.materialIndex; - frame->getMaterial(i).allocateFaces(facesCount); - char **materialName = &GEOMETRY.materialList.materials[materialIndex].textures[0].textureName.text; - frame->getMaterial(i).setName(*materialName); - for (u32 j = 0; j < facesCount; j++) - { - frame->getMaterial(i).setVertexFace(j, CURR_SPLIT.vertexInformation[j].vertex1); - frame->getMaterial(i).setNormalFace(j, CURR_SPLIT.vertexInformation[j].vertex1); - frame->getMaterial(i).setSTFace(j, CURR_SPLIT.vertexInformation[j].vertex1); - } - } - - frame->calculateBoundingBox(); -} - -void DffLoader::serialize(RwClump &t_clump, u8 *t_data, float t_scale) +void DffLoader::serialize(MeshFrame *o_result, u8 t_invertT, u8 *t_data, float t_scale) { u32 ptrPos = 0; - readSectionHeader(t_clump, t_data, ptrPos); - readSectionHeader(t_clump.data, t_data, ptrPos); - readClumpData(t_clump.data, t_data, ptrPos); - readSectionHeader(t_clump.frameList, t_data, ptrPos); - readSectionHeader(t_clump.frameList.data, t_data, ptrPos); - readFrameListData(t_clump.frameList.data, t_data, ptrPos); - t_clump.frameList.extensions = new RwFrameListExtension[t_clump.frameList.data.frameCount]; - for (u32 i = 0; i < t_clump.frameList.data.frameCount; i++) + // readSectionHeader(t_clump, t_data, ptrPos); + // readSectionHeader(t_clump.data, t_data, ptrPos); + // readClumpData(t_clump.data, t_data, ptrPos); + for (u8 i = 0; i < 3 * 3; i++) + ptrPos += sizeof(u32); + + // readSectionHeader(t_clump.frameList, t_data, ptrPos); + // readSectionHeader(t_clump.frameList.data, t_data, ptrPos); + // readFrameListData(t_clump.frameList.data, t_data, ptrPos); + // t_clump.frameList.extensions = new RwFrameListExtension[t_clump.frameList.data.frameCount]; + // for (u32 i = 0; i < t_clump.frameList.data.frameCount; i++) + // { + // readSectionHeader(t_clump.frameList.extensions[i], t_data, ptrPos); + // ptrPos += t_clump.frameList.extensions[i].sectionSize; + // } + RwSectionHeader header1 = RwSectionHeader(); + readSectionHeader(header1, t_data, ptrPos); + ptrPos += header1.sectionSize; + + // readSectionHeader(t_clump.geometryList, t_data, ptrPos); + // readSectionHeader(t_clump.geometryList.data, t_data, ptrPos); + for (u8 i = 0; i < 2 * 3; i++) + ptrPos += sizeof(u32); + + // readGeometryListData(t_clump.geometryList.data, t_data, ptrPos); + ptrPos += sizeof(u32); + + // readSectionHeader(geometry, t_data, ptrPos); + // readSectionHeader(geometry.data, t_data, ptrPos); + for (size_t i = 0; i < 2 * 3; i++) + ptrPos += sizeof(u32); + + readGeometryData(o_result, t_invertT, t_data, ptrPos, t_scale); + + // readSectionHeader(geometry.materialList, t_data, ptrPos); + // readSectionHeader(geometry.materialList.data, t_data, ptrPos); + for (size_t i = 0; i < 2 * 3; i++) + ptrPos += sizeof(u32); + + RwMaterialListData materialListData = RwMaterialListData(); + readMaterialListData(materialListData, t_data, ptrPos); + u32 materialCount = materialListData.materialCount; + + char **materialNames = new char *[materialCount]; + for (u32 j = 0; j < materialCount; j++) { - readSectionHeader(t_clump.frameList.extensions[i], t_data, ptrPos); - ptrPos += t_clump.frameList.extensions[i].sectionSize; + // readSectionHeader(geometry.materialList.materials[j], t_data, ptrPos); + for (size_t i = 0; i < 3; i++) + ptrPos += sizeof(u32); + + // RwMaterialData materialData = RwMaterialData(); + // readSectionHeader(materialData, t_data, ptrPos); + // readMaterialData(materialData, t_data, ptrPos); + RwSectionHeader header1 = RwSectionHeader(); + readSectionHeader(header1, t_data, ptrPos); + ptrPos += header1.sectionSize; + + // for (u32 k = 0; k < textureCount; k++) + // { + + // readSectionHeader(geometry.materialList.materials[j].textures[k], t_data, ptrPos); + // readSectionHeader(geometry.materialList.materials[j].textures[k].data, t_data, ptrPos); + for (size_t i = 0; i < 2 * 3; i++) + ptrPos += sizeof(u32); + + // readTextureData(geometry.materialList.materials[j].textures[k].data, t_data, ptrPos); + ptrPos += sizeof(u32); + + RwSectionHeader header1b = RwSectionHeader(); + readSectionHeader(header1b, t_data, ptrPos); + materialNames[j] = readString(t_data, ptrPos, header1b.sectionSize); + + // readSectionHeader(geometry.materialList.materials[j].textures[k].textureAlphaName, t_data, ptrPos); + // readStringData(geometry.materialList.materials[j].textures[k].textureAlphaName, t_data, ptrPos); + RwSectionHeader header2 = RwSectionHeader(); + readSectionHeader(header2, t_data, ptrPos); + ptrPos += header2.sectionSize; + + // The content of extension is Sky Mipmap Val + // readSectionHeader(geometry.materialList.materials[j].textures[k].extension, t_data, ptrPos); + RwSectionHeader header3 = RwSectionHeader(); + readSectionHeader(header3, t_data, ptrPos); + ptrPos += header3.sectionSize; + // } + + // Probably always void extension + // readSectionHeader(geometry.materialList.materials[j].extension, t_data, ptrPos); + RwSectionHeader header4 = RwSectionHeader(); + readSectionHeader(header4, t_data, ptrPos); + ptrPos += header4.sectionSize; } + // delete[] materialNames; // TODO - readSectionHeader(t_clump.geometryList, t_data, ptrPos); - readSectionHeader(t_clump.geometryList.data, t_data, ptrPos); - readGeometryListData(t_clump.geometryList.data, t_data, ptrPos); + // For Bin Mesh aka Material split + // readSectionHeader(geometry.extension, t_data, ptrPos); + for (size_t i = 0; i < 3; i++) + ptrPos += sizeof(u32); + readGeometryExtension(o_result, materialNames, t_data, ptrPos); - t_clump.geometryList.geometries = new RwGeometry[t_clump.geometryList.data.geometryCount]; - printf("Geometries:%d\n", t_clump.geometryList.data.geometryCount); - for (u32 i = 0; i < t_clump.geometryList.data.geometryCount; i++) - { - readSectionHeader(t_clump.geometryList.geometries[i], t_data, ptrPos); - readSectionHeader(t_clump.geometryList.geometries[i].data, t_data, ptrPos); - readGeometryData(t_clump.geometryList.geometries[i].data, t_data, ptrPos, t_scale); + for (size_t i = 0; i < materialCount; i++) + delete[] materialNames[i]; - readSectionHeader(t_clump.geometryList.geometries[i].materialList, t_data, ptrPos); - readSectionHeader(t_clump.geometryList.geometries[i].materialList.data, t_data, ptrPos); - readMaterialListData(t_clump.geometryList.geometries[i].materialList.data, t_data, ptrPos); + delete materialNames; - u32 materialCount = t_clump.geometryList.geometries[i].materialList.data.materialCount; - printf("Materials:%d\n", materialCount); + // ptrPos += geometry.extension.sectionSize; - t_clump.geometryList.geometries[i].materialList.materials = new RwMaterial[materialCount]; - for (u32 j = 0; j < materialCount; j++) - { - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j], t_data, ptrPos); - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j].data, t_data, ptrPos); - readMaterialData(t_clump.geometryList.geometries[i].materialList.materials[j].data, t_data, ptrPos); - - u32 textureCount = t_clump.geometryList.geometries[i].materialList.materials[j].data.textureCount; - t_clump.geometryList.geometries[i].materialList.materials[j].textures = new RwTexture[textureCount]; - for (u32 k = 0; k < textureCount; k++) - { - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k], t_data, ptrPos); - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].data, t_data, ptrPos); - readTextureData(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].data, t_data, ptrPos); - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].textureName, t_data, ptrPos); - readStringData(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].textureName, t_data, ptrPos); - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].textureAlphaName, t_data, ptrPos); - readStringData(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].textureAlphaName, t_data, ptrPos); - - // The content of extension is Sky Mipmap Val - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].extension, t_data, ptrPos); - ptrPos += t_clump.geometryList.geometries[i].materialList.materials[j].textures[k].extension.sectionSize; - } - // Probably always void extension - readSectionHeader(t_clump.geometryList.geometries[i].materialList.materials[j].extension, t_data, ptrPos); - ptrPos += t_clump.geometryList.geometries[i].materialList.materials[j].extension.sectionSize; - } - // For Bin Mesh aka Material split - readSectionHeader(t_clump.geometryList.geometries[i].extension, t_data, ptrPos); - readGeometryExtension(t_clump.geometryList.geometries[i].extension, t_data, ptrPos); - ptrPos += t_clump.geometryList.geometries[i].extension.sectionSize; - } - - readSectionHeader(t_clump.atomic, t_data, ptrPos); - readSectionHeader(t_clump.atomic.data, t_data, ptrPos); - ptrPos += t_clump.atomic.data.sectionSize; + // readSectionHeader(t_clump.atomic, t_data, ptrPos); + // readSectionHeader(t_clump.atomic.data, t_data, ptrPos); + // ptrPos += t_clump.atomic.data.sectionSize; } void DffLoader::readSectionHeader(RwSectionHeader &t_sh, u8 *t_buffer, u32 &t_ptrPos) @@ -192,139 +177,151 @@ void DffLoader::readSectionHeader(RwSectionHeader &t_sh, u8 *t_buffer, u32 &t_pt void DffLoader::readFrameListData(RwFrameListData &t_frd, u8 *t_buffer, u32 &t_ptrPos) { - t_frd.frameCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - printf("Frame count:%d\n", t_frd.frameCount); - t_frd.frameInformation = new RwFrameListChunk[t_frd.frameCount]; + // t_frd.frameCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + // printf("Frame count:%d\n", t_frd.frameCount); + // t_frd.frameInformation = new RwFrameListChunk[t_frd.frameCount]; - for (u32 i = 0; i < t_frd.frameCount; i++) - { - t_frd.frameInformation[i].rotationalMatrix = new float[t_frd.ROT_MAT_DIM]; - for (u32 j = 0; j < t_frd.ROT_MAT_DIM; j++) - t_frd.frameInformation[i].rotationalMatrix[j] = readFloatFromArrayLE(t_buffer, t_ptrPos); + // for (u32 i = 0; i < t_frd.frameCount; i++) + // { + // t_frd.frameInformation[i].rotationalMatrix = new float[t_frd.ROT_MAT_DIM]; + // for (u32 j = 0; j < t_frd.ROT_MAT_DIM; j++) + // t_frd.frameInformation[i].rotationalMatrix[j] = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_frd.frameInformation[i].coordinatesOffsetX = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_frd.frameInformation[i].coordinatesOffsetY = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_frd.frameInformation[i].coordinatesOffsetZ = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_frd.frameInformation[i] - .parentFrame = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_frd.frameInformation[i].unk1 = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - } + // t_frd.frameInformation[i].coordinatesOffsetX = readFloatFromArrayLE(t_buffer, t_ptrPos); + // t_frd.frameInformation[i].coordinatesOffsetY = readFloatFromArrayLE(t_buffer, t_ptrPos); + // t_frd.frameInformation[i].coordinatesOffsetZ = readFloatFromArrayLE(t_buffer, t_ptrPos); + // t_frd.frameInformation[i] + // .parentFrame = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + // t_frd.frameInformation[i].unk1 = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + // } } void DffLoader::readClumpData(RwClumpData &t_cd, u8 *t_buffer, u32 &t_ptrPos) { - t_cd.objectCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_cd.unk1 = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_cd.unk2 = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + // t_cd.objectCount = readDwordFromArrayLE(t_buffer, t_ptrPos); + // t_cd.unk1 = readDwordFromArrayLE(t_buffer, t_ptrPos); + // t_cd.unk2 = readDwordFromArrayLE(t_buffer, t_ptrPos); } void DffLoader::readGeometryListData(RwGeometryListData &t_gld, u8 *t_buffer, u32 &t_ptrPos) { - t_gld.geometryCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + // t_gld.geometryCount = readDwordFromArrayLE(t_buffer, t_ptrPos); } -void DffLoader::readGeometryExtension(RwGeometryExtension &t_ge, u8 *t_buffer, u32 &t_ptrPos) +void DffLoader::readGeometryExtension(MeshFrame *o_frame, char **materialNames, u8 *t_buffer, u32 &t_ptrPos) { for (u8 i = 0; i < 3; i++) t_ptrPos += sizeof(u32); - t_ge.materialSplit.header.triangleStrip = readDwordFromArrayLE(t_buffer, t_ptrPos); - t_ge.materialSplit.header.splitCount = readDwordFromArrayLE(t_buffer, t_ptrPos); - t_ge.materialSplit.header.faceCount = readDwordFromArrayLE(t_buffer, t_ptrPos); + RwMaterialSplitHeader header = RwMaterialSplitHeader(); + header.triangleStrip = readDwordFromArrayLE(t_buffer, t_ptrPos); + header.splitCount = readDwordFromArrayLE(t_buffer, t_ptrPos); + header.faceCount = readDwordFromArrayLE(t_buffer, t_ptrPos); - t_ge.materialSplit.splitInformation = new RwGeometryListInfoChunk[t_ge.materialSplit.header.splitCount]; - for (u32 i = 0; i < t_ge.materialSplit.header.splitCount; i++) + o_frame->allocateMaterials(header.splitCount); + for (u32 i = 0; i < header.splitCount; i++) { - t_ge.materialSplit.splitInformation[i].faceIndex = readDwordFromArrayLE(t_buffer, t_ptrPos); - t_ge.materialSplit.splitInformation[i].materialIndex = readDwordFromArrayLE(t_buffer, t_ptrPos); - - t_ge.materialSplit.splitInformation[i].vertexInformation = new RwGeometryListVertexInfoChunk[t_ge.materialSplit.splitInformation[i].faceIndex]; - for (u32 j = 0; j < t_ge.materialSplit.splitInformation[i].faceIndex; j++) - t_ge.materialSplit.splitInformation[i].vertexInformation[j].vertex1 = readDwordFromArrayLE(t_buffer, t_ptrPos); + u32 facesCount = readDwordFromArrayLE(t_buffer, t_ptrPos); + u32 materialIndex = readDwordFromArrayLE(t_buffer, t_ptrPos); + o_frame->getMaterial(i).allocateFaces(facesCount); + o_frame->getMaterial(i).setName(materialNames[materialIndex]); + for (u32 j = 0; j < facesCount; j++) + { + u32 vertex1 = readDwordFromArrayLE(t_buffer, t_ptrPos); + o_frame->getMaterial(i).setVertexFace(j, vertex1); + o_frame->getMaterial(i).setNormalFace(j, vertex1); + o_frame->getMaterial(i).setSTFace(j, vertex1); + } } } -void DffLoader::readGeometryData(RwGeometryData &t_gd, u8 *t_buffer, u32 &t_ptrPos, float t_scale) +void DffLoader::readGeometryData(MeshFrame *o_frame, u8 t_invertT, u8 *t_buffer, u32 &t_ptrPos, float t_scale) { - t_gd.dataHeader.flags = readWordFromArrayLE(t_buffer, t_ptrPos); - t_gd.dataHeader.unk1 = readWordFromArrayLE(t_buffer, t_ptrPos); - t_gd.dataHeader.triangleCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_gd.dataHeader.vertexCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_gd.dataHeader.morphTargetCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + Vector3 tempVec = Vector3(); + Point tempPoint = Point(); + + RwGeometryDataHeader header; + header.flags = readWordFromArrayLE(t_buffer, t_ptrPos); + header.unk1 = readWordFromArrayLE(t_buffer, t_ptrPos); + header.triangleCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + header.vertexCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + header.morphTargetCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); if (false) - { // version equals 4099 according to old documentation, disabled as for now - t_gd.lightingHeader.ambient = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_gd.lightingHeader.diffuse = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_gd.lightingHeader.specular = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + { // version equals 4099 according to old documentation, disabled as for now + readDwordFromArrayLE(t_buffer, t_ptrPos); // ambient + readDwordFromArrayLE(t_buffer, t_ptrPos); // diffuse + readDwordFromArrayLE(t_buffer, t_ptrPos); // specular } - if (t_gd.dataHeader.flags & rwOBJECT_VERTEX_PRELIT) - { - t_gd.colorInformation = new RwGeometryDataColorInformationChunk[t_gd.dataHeader.vertexCount]; - for (u32 i = 0; i < t_gd.dataHeader.vertexCount; i++) + if (header.flags & rwOBJECT_VERTEX_PRELIT) + for (u32 i = 0; i < header.vertexCount; i++) { - t_gd.colorInformation[i].red = readByteFromArrayLE(t_buffer, t_ptrPos); - t_gd.colorInformation[i].green = readByteFromArrayLE(t_buffer, t_ptrPos); - t_gd.colorInformation[i].blue = readByteFromArrayLE(t_buffer, t_ptrPos); - t_gd.colorInformation[i].alpha = readByteFromArrayLE(t_buffer, t_ptrPos); + readByteFromArrayLE(t_buffer, t_ptrPos); // r + readByteFromArrayLE(t_buffer, t_ptrPos); // g + readByteFromArrayLE(t_buffer, t_ptrPos); // b + readByteFromArrayLE(t_buffer, t_ptrPos); // a + } + + if (header.flags & rwOBJECT_VERTEX_TEXTURED) + { + o_frame->allocateSTs(header.vertexCount); + for (u32 i = 0; i < header.vertexCount; i++) + { + float u = readFloatFromArrayLE(t_buffer, t_ptrPos); + float v = readFloatFromArrayLE(t_buffer, t_ptrPos); + tempPoint.set(u, v); + if (t_invertT) + tempPoint.y = 1.0F - tempPoint.y; + o_frame->setST(i, tempPoint); } } - if (t_gd.dataHeader.flags & rwOBJECT_VERTEX_TEXTURED) + for (u32 i = 0; i < header.triangleCount; i++) { - t_gd.textureMappingInformation = new RwGeometryDataTextureMappingInformationChunk[t_gd.dataHeader.vertexCount]; - for (u32 i = 0; i < t_gd.dataHeader.vertexCount; i++) - { - t_gd.textureMappingInformation[i].u = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_gd.textureMappingInformation[i].v = readFloatFromArrayLE(t_buffer, t_ptrPos); - } + readWordFromArrayLE(t_buffer, t_ptrPos); // vert2 + readWordFromArrayLE(t_buffer, t_ptrPos); // vert1 + readWordFromArrayLE(t_buffer, t_ptrPos); // flags + readWordFromArrayLE(t_buffer, t_ptrPos); // vert3 } - t_gd.faceInformation = new RwGeometryDataFaceInformation[t_gd.dataHeader.triangleCount]; - for (u32 i = 0; i < t_gd.dataHeader.triangleCount; i++) + for (size_t i = 0; i < 6; i++) + t_ptrPos += sizeof(u32); + // t_gd.nonameInfo.boundingSphereX = readFloatFromArrayLE(t_buffer, t_ptrPos); + // t_gd.nonameInfo.boundingSphereY = readFloatFromArrayLE(t_buffer, t_ptrPos); + // t_gd.nonameInfo.boundingSphereZ = readFloatFromArrayLE(t_buffer, t_ptrPos); + // t_gd.nonameInfo.boundingSphereR = readFloatFromArrayLE(t_buffer, t_ptrPos); + // t_gd.nonameInfo.hasPosition = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + // t_gd.nonameInfo.hasNormals = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); + + o_frame->allocateVertices(header.vertexCount); + for (u32 i = 0; i < header.vertexCount; i++) { - t_gd.faceInformation[i].vertex2 = readWordFromArrayLE(t_buffer, t_ptrPos); - t_gd.faceInformation[i].vertex1 = readWordFromArrayLE(t_buffer, t_ptrPos); - t_gd.faceInformation[i].flags = readWordFromArrayLE(t_buffer, t_ptrPos); - t_gd.faceInformation[i].vertex3 = readWordFromArrayLE(t_buffer, t_ptrPos); + float x = readFloatFromArrayLE(t_buffer, t_ptrPos) * t_scale; + float y = readFloatFromArrayLE(t_buffer, t_ptrPos) * t_scale; + float z = readFloatFromArrayLE(t_buffer, t_ptrPos) * t_scale; + tempVec.set(x, y, z); + o_frame->setVertex(i, tempVec); } - t_gd.nonameInfo.boundingSphereX = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_gd.nonameInfo.boundingSphereY = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_gd.nonameInfo.boundingSphereZ = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_gd.nonameInfo.boundingSphereR = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_gd.nonameInfo.hasPosition = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_gd.nonameInfo.hasNormals = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - - t_gd.vertexInformation = new Vector3[t_gd.dataHeader.vertexCount]; - for (u32 i = 0; i < t_gd.dataHeader.vertexCount; i++) + o_frame->allocateNormals(header.vertexCount); + for (u32 i = 0; i < header.vertexCount; i++) { - t_gd.vertexInformation[i].x = readFloatFromArrayLE(t_buffer, t_ptrPos) * t_scale; - t_gd.vertexInformation[i].y = readFloatFromArrayLE(t_buffer, t_ptrPos) * t_scale; - t_gd.vertexInformation[i].z = readFloatFromArrayLE(t_buffer, t_ptrPos) * t_scale; - } - - if (t_gd.dataHeader.flags & rwOBJECT_VERTEX_NORMALS) - { - t_gd.normalInformation = new Vector3[t_gd.dataHeader.vertexCount]; - for (u32 i = 0; i < t_gd.dataHeader.vertexCount; i++) - { - t_gd.normalInformation[i].x = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_gd.normalInformation[i].y = readFloatFromArrayLE(t_buffer, t_ptrPos); - t_gd.normalInformation[i].z = readFloatFromArrayLE(t_buffer, t_ptrPos); - } + float x = readFloatFromArrayLE(t_buffer, t_ptrPos); + float y = readFloatFromArrayLE(t_buffer, t_ptrPos); + float z = readFloatFromArrayLE(t_buffer, t_ptrPos); + tempVec.set(x, y, z); + o_frame->setNormal(i, tempVec); } } void DffLoader::readMaterialListData(RwMaterialListData &t_mld, u8 *t_buffer, u32 &t_ptrPos) { t_mld.materialCount = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - t_mld.arrayOfUnks = new u32[t_mld.materialCount]; + // t_mld.arrayOfUnks = new u32[t_mld.materialCount]; for (u32 i = 0; i < t_mld.materialCount; i++) - { - t_mld.arrayOfUnks[i] = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); - } + readDwordFromArrayLE(t_buffer, t_ptrPos); + // t_mld.arrayOfUnks[i] = DffLoader::readDwordFromArrayLE(t_buffer, t_ptrPos); } void DffLoader::readMaterialData(RwMaterialData &t_md, u8 *t_buffer, u32 &t_ptrPos) @@ -381,15 +378,6 @@ float DffLoader::readFloatFromArrayLE(u8 *t_buffer, u32 &t_ptrPos) return res; } -u8 *DffLoader::readData(u8 *t_buffer, u32 &t_ptrPos, u32 t_dataSize) -{ - u8 *arr = new u8[t_dataSize]; - for (u32 i = 0; i < t_dataSize; ++i) - arr[i] = t_buffer[i + t_ptrPos]; - t_ptrPos += t_dataSize; - return arr; -} - char *DffLoader::readString(u8 *t_buffer, u32 &t_ptrPos, u32 t_dataSize) { u32 strLength = String::getLength((char *)&t_buffer[t_ptrPos]); diff --git a/src/engine/models/mesh.cpp b/src/engine/models/mesh.cpp index e920e5d..1c94c39 100644 --- a/src/engine/models/mesh.cpp +++ b/src/engine/models/mesh.cpp @@ -24,10 +24,11 @@ Mesh::Mesh() { + id = rand() % 1000000; shouldBeFrustumCulled = true; shouldBeBackfaceCulled = false; shouldBeLighted = false; - id = rand() % 1000000; + _isMother = false; scale = 1.0F; framesCount = 0; animState.startFrame = 0; @@ -39,8 +40,8 @@ Mesh::Mesh() animState.isStayFrameSet = false; animState.nextFrame = 0; animState.speed = 0.1F; - _isMother = false; setDefaultColor(); + setDefaultLODAndClut(); } Mesh::~Mesh() @@ -131,7 +132,10 @@ void Mesh::playAnimation(const u32 &t_startFrame, const u32 &t_endFrame) PRINT_ERR("End frame value is too high. Valid range: (0, getFramesCount()-1)"); animState.startFrame = t_startFrame; animState.endFrame = t_endFrame; - animState.nextFrame = t_startFrame; + if (animState.currentFrame == t_startFrame) + animState.nextFrame = t_endFrame; + else + animState.nextFrame = t_startFrame; } else if (framesCount == 0) PRINT_ERR("Cant play animation, because no mesh data was loaded!"); @@ -157,14 +161,6 @@ void Mesh::playAnimation(const u32 &t_startFrame, const u32 &t_endFrame, const u PRINT_ERR("Cant play animation, because this mesh have only one frame."); } -u32 Mesh::getFacesCount() -{ - u32 result = 0; // TODO - for (u16 i = 0; i < frames[0].getMaterialsCount(); i++) - result += frames[0].getMaterial(i).getFacesCount(); - return result; -} - void Mesh::animate() { animState.interpolation += animState.speed; @@ -189,29 +185,36 @@ void Mesh::animate() u32 Mesh::getDrawData(u32 t_materialIndex, VECTOR *o_vertices, VECTOR *o_normals, VECTOR *o_coordinates, Vector3 &t_cameraPos) { + u32 addedFaces = 0; #define CURR_FRAME frames[animState.currentFrame] #define NEXT_FRAME frames[animState.nextFrame] -#define MATERIAL CURR_FRAME.getMaterial(t_materialIndex) -#define CURR_VERT CURR_FRAME.getVertex(MATERIAL.getVertexFace(matI + vertI)) -#define NEXT_VERT NEXT_FRAME.getVertex(MATERIAL.getVertexFace(matI + vertI)) - u32 addedFaces = 0; - for (u32 matI = 0; matI < MATERIAL.getFacesCount(); matI += 3) + MeshMaterial *material = &CURR_FRAME.getMaterial(t_materialIndex); // cache + Vector3 *verts = CURR_FRAME.getVertices(); // cache + Vector3 *nextVerts = NEXT_FRAME.getVertices(); // cache + Point *sts = CURR_FRAME.getSTs(); // cache + Vector3 *normals = CURR_FRAME.getNormals(); // cache +#define CURR_VERT verts[material->getVertexFace(matI + vertI)] +#define CURR_ST sts[material->getSTFace(matI + vertI)] +#define CURR_NORMAL normals[material->getNormalFace(matI + vertI)] +#define NEXT_VERT nextVerts[material->getVertexFace(matI + vertI)] + + for (u32 matI = 0; matI < material->getFacesCount(); matI += 3) { for (u32 vertI = 0; vertI < 3; vertI++) if (animState.currentFrame != animState.nextFrame) calc3Vectors[vertI].setByLerp(CURR_VERT, NEXT_VERT, animState.interpolation, scale); if (!shouldBeBackfaceCulled || - Vector3::shouldBeBackfaceCulled(&t_cameraPos, &calc3Vectors[2], &calc3Vectors[1], &calc3Vectors[0])) + Vector3::shouldBeBackfaceCulled(&t_cameraPos, &calc3Vectors[0], &calc3Vectors[1], &calc3Vectors[2])) for (u32 vertI = 0; vertI < 3; vertI++) { if (animState.currentFrame == animState.nextFrame) { - o_vertices[addedFaces][0] = CURR_FRAME.getVertex(MATERIAL.getVertexFace(matI + vertI)).x; - o_vertices[addedFaces][1] = CURR_FRAME.getVertex(MATERIAL.getVertexFace(matI + vertI)).y; - o_vertices[addedFaces][2] = CURR_FRAME.getVertex(MATERIAL.getVertexFace(matI + vertI)).z; + o_vertices[addedFaces][0] = CURR_VERT.x; + o_vertices[addedFaces][1] = CURR_VERT.y; + o_vertices[addedFaces][2] = CURR_VERT.z; } else { @@ -221,13 +224,13 @@ u32 Mesh::getDrawData(u32 t_materialIndex, VECTOR *o_vertices, VECTOR *o_normals } o_vertices[addedFaces][3] = 1.0F; - o_normals[addedFaces][0] = CURR_FRAME.getNormal(MATERIAL.getNormalFace(matI + vertI)).x; - o_normals[addedFaces][1] = CURR_FRAME.getNormal(MATERIAL.getNormalFace(matI + vertI)).y; - o_normals[addedFaces][2] = CURR_FRAME.getNormal(MATERIAL.getNormalFace(matI + vertI)).z; + o_normals[addedFaces][0] = CURR_NORMAL.x; + o_normals[addedFaces][1] = CURR_NORMAL.y; + o_normals[addedFaces][2] = CURR_NORMAL.z; o_normals[addedFaces][3] = 1.0F; - o_coordinates[addedFaces][0] = CURR_FRAME.getST(MATERIAL.getSTFace(matI + vertI)).x; - o_coordinates[addedFaces][1] = CURR_FRAME.getST(MATERIAL.getSTFace(matI + vertI)).y; + o_coordinates[addedFaces][0] = CURR_ST.x; + o_coordinates[addedFaces][1] = CURR_ST.y; o_coordinates[addedFaces][2] = 1.0F; o_coordinates[addedFaces++][3] = 1.0F; } @@ -235,64 +238,6 @@ u32 Mesh::getDrawData(u32 t_materialIndex, VECTOR *o_vertices, VECTOR *o_normals return addedFaces; } -void Mesh::setAnimSpeed(float t_value) -{ - animState.speed = t_value; -} - -u32 Mesh::getVertexCount() -{ - if (framesCount > 0) - return getFacesCount(); - else - { - PRINT_ERR("Can't get vertex count, because mesh data was loaded!"); - return 0; - } -} - -/** Set's default object color + no transparency */ -void Mesh::setDefaultColor() -{ - color.r = 0x80; - color.g = 0x80; - color.b = 0x80; - color.a = 0x80; - color.q = 1.0F; -} - -/** Calculates minimum and maximum X, Y, Z of this 3D objects vertices + current position */ -// void Mesh::getMinMax(Vector3 *t_min, Vector3 *t_max) -// { -// Vector3 calc = Vector3(); -// u8 isInitialized = 0; -// for (u32 i = 0; i < 8; i++) -// { -// getFarthestVertex(&calc, i); -// if (isInitialized == 0) -// { -// isInitialized = 1; -// t_min->set(calc); -// t_max->set(calc); -// } - -// if (t_min->x > calc.x) -// t_min->x = calc.x; -// if (calc.x > t_max->x) -// t_max->x = calc.x; - -// if (t_min->y > calc.y) -// t_min->y = calc.y; -// if (calc.y > t_max->y) -// t_max->y = calc.y; - -// if (t_min->z > calc.z) -// t_min->z = calc.z; -// if (calc.z > t_max->z) -// t_max->z = calc.z; -// } -// } - void Mesh::getCurrentBoundingBoxVertex(Vector3 &o_result, const u32 &t_index) { o_result.set( @@ -301,26 +246,6 @@ void Mesh::getCurrentBoundingBoxVertex(Vector3 &o_result, const u32 &t_index) frames[animState.currentFrame].getBoundingBox(t_index).z + position.z); } -/** Sets texture level of details settings and CLUT settings */ -void Mesh::setupLodAndClut() -{ - PRINT_LOG("Setting LOD, CLUT"); - lod.calculation = LOD_USE_K; - lod.max_level = 0; - lod.mag_filter = LOD_MAG_NEAREST; - lod.min_filter = LOD_MIN_NEAREST; - lod.l = 0; - lod.k = 0.0F; - - clut.storage_mode = CLUT_STORAGE_MODE1; - clut.start = 0; - clut.psm = 0; - clut.load_method = CLUT_NO_LOAD; - clut.address = 0; - PRINT_LOG("LOD, CLUT set!"); -} - -/** Check if box is visible in view frustum */ u8 Mesh::isInFrustum(Plane *t_frustumPlanes) { Vector3 boxCalcTemp; @@ -349,3 +274,32 @@ u8 Mesh::isInFrustum(Plane *t_frustumPlanes) } return boxResult; } + +/** Set's default object color + no transparency */ +void Mesh::setDefaultColor() +{ + color.r = 0x80; + color.g = 0x80; + color.b = 0x80; + color.a = 0x80; + color.q = 1.0F; +} + +/** Sets texture level of details settings and CLUT settings */ +void Mesh::setDefaultLODAndClut() +{ + PRINT_LOG("Setting LOD, CLUT"); + lod.calculation = LOD_USE_K; + lod.max_level = 0; + lod.mag_filter = LOD_MAG_NEAREST; + lod.min_filter = LOD_MIN_NEAREST; + lod.l = 0; + lod.k = 0.0F; + + clut.storage_mode = CLUT_STORAGE_MODE1; + clut.start = 0; + clut.psm = 0; + clut.load_method = CLUT_NO_LOAD; + clut.address = 0; + PRINT_LOG("LOD, CLUT set!"); +} diff --git a/src/engine/modules/gif_sender.cpp b/src/engine/modules/gif_sender.cpp index 7f694fd..4966a88 100644 --- a/src/engine/modules/gif_sender.cpp +++ b/src/engine/modules/gif_sender.cpp @@ -171,7 +171,7 @@ void GifSender::addObjects(RenderData *t_renderData, Mesh **t_objects3D, u32 t_a */ u32 GifSender::calc3DObject(Matrix t_perspective, Mesh &t_mesh, RenderData *t_renderData, LightBulb *t_bulbs, u16 t_bulbsCount) { - u32 vertexCount = t_mesh.getVertexCount(); + u32 vertexCount = t_mesh.getVertexCount(); // TODO err VECTOR *vertices = new VECTOR[vertexCount]; VECTOR *normals = new VECTOR[vertexCount]; diff --git a/src/engine/modules/renderer.cpp b/src/engine/modules/renderer.cpp index 16b92b1..489addd 100644 --- a/src/engine/modules/renderer.cpp +++ b/src/engine/modules/renderer.cpp @@ -84,7 +84,7 @@ void Renderer::deallocateTextureBuffer() void Renderer::changeTexture(Mesh *t_mesh, u32 t_materialId) { - MeshTexture *tex = textureRepo.getByMesh(t_mesh->id, t_materialId); + MeshTexture *tex = textureRepo.getByMesh(t_mesh->getId(), t_materialId); if (tex != NULL) { if (tex->getId() != lastTextureId) @@ -209,22 +209,21 @@ void Renderer::draw(Mesh *t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount) if (!t_mesh->isDataLoaded()) PRINT_ERR("Can't draw, because no mesh data was loaded!"); - u32 vertCount = t_mesh->getVertexCount(); - VECTOR *vertices = new VECTOR[vertCount]; - VECTOR *normals = new VECTOR[vertCount]; - VECTOR *coordinates = new VECTOR[vertCount]; - - if (t_mesh->animState.currentFrame != t_mesh->animState.nextFrame) + if (t_mesh->getCurrentAnimationFrame() != t_mesh->getNextAnimationFrame()) t_mesh->animate(); for (u32 i = 0; i < t_mesh->getMaterialsCount(); i++) { + u32 vertCount = t_mesh->getMaterial(i).getFacesCount(); + VECTOR *vertices = new VECTOR[vertCount]; + VECTOR *normals = new VECTOR[vertCount]; + VECTOR *coordinates = new VECTOR[vertCount]; changeTexture(t_mesh, t_mesh->getMaterial(i).getId()); vertCount = t_mesh->getDrawData(i, vertices, normals, coordinates, *renderData.cameraPosition); vifSender->drawMesh(&renderData, perspective, vertCount, vertices, normals, coordinates, t_mesh, t_bulbs, t_bulbsCount, &textureBuffer); + delete[] vertices; + delete[] normals; + delete[] coordinates; } - delete[] vertices; - delete[] normals; - delete[] coordinates; } /** PATH1 Many */ diff --git a/src/engine/modules/texture_repository.cpp b/src/engine/modules/texture_repository.cpp index 9e05e85..255afc6 100644 --- a/src/engine/modules/texture_repository.cpp +++ b/src/engine/modules/texture_repository.cpp @@ -51,7 +51,7 @@ void TextureRepository::addByMesh(char *t_path, Mesh &mesh) MeshTexture *texture = new MeshTexture(); loader.load(*texture, t_path, mesh.getMaterial(i).getName(), ".bmp"); texture->setName(mesh.getMaterial(i).getName()); - texture->addLink(mesh.id, mesh.getMaterial(i).getId()); + texture->addLink(mesh.getId(), mesh.getMaterial(i).getId()); textures.push_back(texture); } } diff --git a/src/samples/ari/ari.cpp b/src/samples/ari/ari.cpp index 9e9eee1..1a25635 100644 --- a/src/samples/ari/ari.cpp +++ b/src/samples/ari/ari.cpp @@ -65,8 +65,8 @@ void calcSpiral(int X, int Y) } // TEST END -#include "models/mesh_frame.hpp" -#include +// TODO 1 - const & in parameters +// TODO 2 - Destructor mesh void Ari::onInit() { @@ -76,62 +76,52 @@ void Ari::onInit() engine.audio.init(0); engine.audio.setVolume(40); engine.audio.loadSong("MOV-CIRC.WAV"); + engine.audio.play(); + texRepo = engine.renderer->getTextureRepository(); - // engine.audio.play(); - // islandAddons = new Mesh(); - // islandAddons->rotation.x = -1.6F; - // islandAddons->loadDff("sunnyisl/", "sunnyisl3.dff", islandPos, 0.1F); - // islandAddons->shouldBeFrustumCulled = false; - - // TODO 1 - Refactor mesh, loaders - // TODO 2 - const & in parameters - // TODO 3 - Destructor mesh - // TODO 4 - Destructor RwClump in dff loader - // TODO 5 - Test mesh copy(); - - // test->shouldBeFrustumCulled = true; - - test = new Mesh(); - skybox = new Mesh(); island = new Mesh(); - island->loadDff("sunnyisl/", "sunnyisl", 0.1F, false); - test->loadMD2("warrior/", "warrior", 0.2F, true); - skybox->loadObj("skybox/", "skybox", 80.0F, false); // po zamianie miejscami dziaƂa - - test->rotation.x = -1.6F; - test->playAnimation(9, 15, 0); - skybox->position.set(0.0F, 10.0F, 0.0F); island->rotation.x = -1.6F; - island->position.set(0.0F, 10.0F, 0.0F); + island->position.set(0.0F, 10.0F, 20.0F); + island->shouldBeFrustumCulled = false; + island->shouldBeBackfaceCulled = true; + + islandAddons = new Mesh(); + islandAddons->loadDff("sunnyisl/", "sunnyisl3", 0.1F, false); + islandAddons->rotation.x = -1.6F; + islandAddons->position.set(0.0F, 10.0F, 20.0F); + islandAddons->shouldBeFrustumCulled = false; + + skybox = new Mesh(); + skybox->loadObj("skybox/", "skybox", 100.0F, false); + + waterFloors = new Mesh *[WATER_TILES_COUNT]; + spirals = new Point[WATER_TILES_COUNT]; + waterFloors[0] = new Mesh(); + waterFloors[0]->loadObj("water/", "water", 5.0F, false); + waterFloors[0]->position.set(0.0F, 8.0F, 0.0F); + texRepo->addByMesh("water/", *waterFloors[0]); + for (u8 i = 0; i < WATER_TILES_COUNT; i++) + { + spirals[i].x = 1.0F; + spirals[i].y = 2.0F; + } + u32 spiralOffset = (u32)Math::sqrt(WATER_TILES_COUNT); + calcSpiral(spiralOffset, spiralOffset); + for (u8 i = 1; i < WATER_TILES_COUNT; i++) + { + waterFloors[i] = new Mesh(); + waterFloors[i]->loadFrom(*waterFloors[0]); + waterFloors[i]->position.set(10.0F * spirals[i].x, 8.0F, 10.0F * spirals[i].y); + texRepo->getByMesh(waterFloors[0]->getId(), waterFloors[0]->getMaterial(0).getId()) + ->addLink(waterFloors[i]->getId(), waterFloors[i]->getMaterial(0).getId()); + } - texRepo->addByMesh("warrior/", *test); - texRepo->addByMesh("skybox/", *skybox); texRepo->addByMesh("sunnyisl/", *island); - - // waterFloors = new Mesh *[WATER_TILES_COUNT]; - // spirals = new Point[WATER_TILES_COUNT]; - // Vector3 initPos = Vector3(0.0F, 8.0F, 0.0F); - // waterFloors[0] = new Mesh(); - // // loadObj("water/", "water", initPos, 5.0F,12); - // // loadObj("water/", "water", initPos, 5.0F); - // waterFloors[0]->loadObj("water/", "water", initPos, 5.0F, 2); - // waterFloors[0]->shouldBeFrustumCulled = true; - // for (u8 i = 0; i < WATER_TILES_COUNT; i++) - // { - // spirals[i].x = 1.0F; - // spirals[i].y = 2.0F; - // } - // u32 spiralOffset = (u32)Math::sqrt(WATER_TILES_COUNT); - // calcSpiral(spiralOffset, spiralOffset); - // for (u8 i = 1; i < WATER_TILES_COUNT; i++) - // { - // waterFloors[i] = new Mesh(); - // Vector3 nextPos = Vector3(10.0F * spirals[i].x, 8.0F, 10.0F * spirals[i].y); - // waterFloors[i]->setObj(nextPos, waterFloors[0]->obj, waterFloors[0]->spec); - // waterFloors[i]->shouldBeFrustumCulled = true; - // } + texRepo->addByMesh("sunnyisl/", *islandAddons); + texRepo->addByMesh("skybox/", *skybox); + texRepo->addByMesh("ari/", player->mesh); } void Ari::initBulb() @@ -145,11 +135,10 @@ void Ari::onUpdate() if (engine.pad.isCrossClicked) printf("FPS:%f\n", engine.fps); camera->update(engine.pad, player->mesh); - engine.renderer->draw(test); engine.renderer->draw(skybox); engine.renderer->draw(island); - // engine.renderer->draw(islandAddons); - // // engine.renderer->draw(&player->mesh); - // for (u8 i = 0; i < WATER_TILES_COUNT; i++) - // engine.renderer->draw(waterFloors[i]); // TODO + engine.renderer->draw(islandAddons); + engine.renderer->draw(&player->mesh); + for (u8 i = 0; i < WATER_TILES_COUNT; i++) + engine.renderer->draw(waterFloors[i]); } diff --git a/src/samples/ari/objects/player.cpp b/src/samples/ari/objects/player.cpp index a343a6b..2f7da88 100644 --- a/src/samples/ari/objects/player.cpp +++ b/src/samples/ari/objects/player.cpp @@ -25,13 +25,13 @@ Player::Player() PRINT_LOG("Creating player object"); this->gravity = 0.1F; this->lift = -1.0F; - Vector3 initPos = Vector3(0.0F, 8.0F, 0.0F); - // this->mesh.loadMD2("ari/", "ari.md2", initPos, 0.0001F); - // this->mesh.shouldBeBackfaceCulled = true; - // this->mesh.shouldBeFrustumCulled = false; - // this->mesh.shouldBeLighted = true; - // this->mesh.setAnimSpeed(0.05F); - // this->mesh.playAnimation(0, 1); + this->mesh.loadMD2("ari/", "ari", 0.0001F, true); + this->mesh.position.set(0.0F, 10.0F, 0.0F); + this->mesh.shouldBeBackfaceCulled = true; + this->mesh.shouldBeFrustumCulled = false; + this->mesh.shouldBeLighted = true; + this->mesh.setAnimSpeed(0.05F); + this->mesh.playAnimation(0, 1); PRINT_LOG("Player object created!"); } diff --git a/src/samples/floors/objects/player.cpp b/src/samples/floors/objects/player.cpp index 819d976..df19049 100644 --- a/src/samples/floors/objects/player.cpp +++ b/src/samples/floors/objects/player.cpp @@ -106,6 +106,38 @@ void Player::onBeforePlayerFloorMove(Floor *floor, float &newY) this->mesh.position.y -= -newY * 1.05F; } +/** Calculates minimum and maximum X, Y, Z of this 3D objects vertices + current position */ +// void Mesh::getMinMax(Vector3 *t_min, Vector3 *t_max) +// { +// Vector3 calc = Vector3(); +// u8 isInitialized = 0; +// for (u32 i = 0; i < 8; i++) +// { +// getFarthestVertex(&calc, i); +// if (isInitialized == 0) +// { +// isInitialized = 1; +// t_min->set(calc); +// t_max->set(calc); +// } + +// if (t_min->x > calc.x) +// t_min->x = calc.x; +// if (calc.x > t_max->x) +// t_max->x = calc.x; + +// if (t_min->y > calc.y) +// t_min->y = calc.y; +// if (calc.y > t_max->y) +// t_max->y = calc.y; + +// if (t_min->z > calc.z) +// t_min->z = calc.z; +// if (calc.z > t_max->z) +// t_max->z = calc.z; +// } +// } + /** Update player position by gravity and update index of current floor */ void Player::updateGravity(Pad &pad, FloorManager &floorManager) {